Changeset 640b3df


Ignore:
Timestamp:
Feb 21, 2023, 4:24:34 PM (3 years ago)
Author:
caparson <caparson@…>
Branches:
ADT, ast-experimental, master
Children:
257a8f5, ce44c5f
Parents:
1180175 (diff), 9a533ba (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge branch 'master' of plg.uwaterloo.ca:software/cfa/cfa-cc

Files:
2 added
2 deleted
58 edited

Legend:

Unmodified
Added
Removed
  • doc/LaTeXmacros/common.sty

    r1180175 r640b3df  
    1111%% Created On       : Sat Apr  9 10:06:17 2016
    1212%% Last Modified By : Peter A. Buhr
    13 %% Last Modified On : Sat Apr  2 17:35:23 2022
    14 %% Update Count     : 570
     13%% Last Modified On : Fri Feb 10 12:09:30 2023
     14%% Update Count     : 581
    1515%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    1616
     
    3030\setlist[itemize,1]{label=\textbullet}% local
    3131%\renewcommand{\labelitemi}{{\raisebox{0.25ex}{\footnotesize$\bullet$}}}
    32 \setlist[enumerate]{listparindent=\parindent}% global
     32\setlist[enumerate]{topsep=0.5ex,parsep=0.25ex,itemsep=0.25ex,listparindent=\parindent}% global
    3333\setlist[enumerate,2]{leftmargin=\parindent,labelsep=*,align=parleft,label=\alph*.}% local
    3434\setlist[description]{topsep=0.5ex,itemsep=0pt,listparindent=\parindent,leftmargin=\parindent,labelsep=1.5ex}
     
    4949\newcommand{\CCseventeen}{\protect\CCIcon{17}\xspace}   % C++17 symbolic name
    5050\newcommand{\CCtwenty}{\protect\CCIcon{20}\xspace}              % C++20 symbolic name
    51 \newcommand{\Csharp}{C\raisebox{-0.7ex}{\Large$^\sharp$}\xspace} % C# symbolic name
     51\newcommand{\Csharp}{C\raisebox{-0.7ex}{\relsize{2}$^\sharp$}\xspace} % C# symbolic name
    5252
    5353%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    5454
    55 \usepackage{pslatex}                                                                    % reduce size of san serif font
     55\usepackage[scaled=0.85]{helvet}                                                % descent Helvetica font and scale to times size
     56\usepackage[T1]{fontenc}
    5657\usepackage{relsize}                                                                    % must be after change to small or selects old size
    5758\usepackage{rotating}
     
    195196\newcommand{\viz}{\VIZ\CheckPeriod}
    196197
     198\newcommand{\VS}{\abbrevFont{vs}}
     199\newcommand{\vs}{\VS\CheckPeriod}
     200
    197201\newenvironment{cquote}{%
    198202        \list{}{\lstset{resetmargins=true,aboveskip=0pt,belowskip=0pt}\topsep=4pt\parsep=0pt\leftmargin=\parindentlnth\rightmargin\leftmargin}%
     
    244248\renewcommand{\reftextpagerange}[2]{\unskip, pp.~\pageref{#1}--\pageref{#2}}
    245249\newcommand{\VRef}[2][Section]{\ifx#1\@empty\else{#1}\nobreakspace\fi\vref{#2}}
     250\newcommand{\VRefrange}[3][Sections]{\ifx#1\@empty\else{#1}\nobreakspace\fi\vrefrange{#2}{#3}}
    246251\newcommand{\VPageref}[2][page]{\ifx#1\@empty\else{#1}\nobreakspace\fi\pageref{#2}}
     252\newcommand{\VPagerefrange}[3][pages]{\ifx#1\@empty\else{#1}\nobreakspace\fi\pageref{#2}{#3}}
    247253
    248254\let\Oldthebibliography\thebibliography
  • doc/LaTeXmacros/common.tex

    r1180175 r640b3df  
    1111%% Created On       : Sat Apr  9 10:06:17 2016
    1212%% Last Modified By : Peter A. Buhr
    13 %% Last Modified On : Tue Apr 26 16:02:48 2022
    14 %% Update Count     : 558
     13%% Last Modified On : Fri Feb 10 11:48:00 2023
     14%% Update Count     : 564
    1515%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    1616
     
    4949\newcommand{\CCseventeen}{\protect\CCIcon{17}\xspace}   % C++17 symbolic name
    5050\newcommand{\CCtwenty}{\protect\CCIcon{20}\xspace}              % C++20 symbolic name
    51 \newcommand{\Csharp}{C\raisebox{-0.7ex}{\Large$^\sharp$}\xspace} % C# symbolic name
     51\newcommand{\Csharp}{C\raisebox{-0.7ex}{\relsize{2}$^\sharp$}\xspace} % C# symbolic name
    5252
    5353%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    5454
    55 \usepackage{pslatex}                                                                    % reduce size of san serif font
     55\usepackage[scaled=0.85]{helvet}                                                % descent Helvetica font and scale to times size
     56\usepackage[T1]{fontenc}
    5657\usepackage{relsize}                                                                    % must be after change to small or selects old size
    5758\usepackage{rotating}
     
    196197\newcommand{\viz}{\VIZ\CheckPeriod}
    197198
     199\newcommand{\VS}{\abbrevFont{vs}}
     200\newcommand{\vs}{\VS\CheckPeriod}
    198201\makeatother
    199202
  • doc/bibliography/pl.bib

    r1180175 r640b3df  
    147147    author      = {Zhang, Yizhou and Salvaneschi, Guido and Beightol, Quinn and Liskov, Barbara and Myers, Andrew C.},
    148148    title       = {Accepting Blame for Safe Tunneled Exceptions},
    149     booktitle   = {Proceedings of the 37th ACM SIGPLAN Conference on Programming Language Design and Implementation},
     149    organization= {Proceedings of the 37th ACM SIGPLAN Conference on Programming Language Design and Implementation},
    150150    series      = {PLDI'16},
    151151    year        = {2016},
     
    196196   },
    197197   comment      = {Mentions Thoth in reference to delegation}
     198}
     199
     200@misc{ActorBenchmarks,
     201    keywords    = {Actors, microbenchmarks, uC++. CAF, AkkaC, AkkaT, ProtoActor},
     202    contributer = {pabuhr@plg},
     203    key         = {ActorBenchmarks},
     204    title       = {Actor Benchmarks},
     205    author      = {Peter A. Buhr and Colby A. Parsons},
     206    howpublished= {\href{https://github.com/pabuhr/ActorExperiments}{https://\-github.com/\-pabuhr/\-ActorExperiments}},
     207    year        = 2022,
    198208}
    199209
     
    245255}
    246256
     257@manual{Ada95,
     258    keywords    = {Ada},
     259    contributer = {pabuhr@plg},
     260    title       = {{A}da Reference Manual},
     261    edition     = {International Standard {ISO}/{IEC} {8652:1995(E)} with {COR.1:2000}},
     262    organization= {Intermetrics, Inc.},
     263    month       = dec,
     264    year        = 1995,
     265    note        = {Language and Standards Libraries}
     266}
     267
     268@manual{Ada12,
     269    keywords    = {ISO/IEC Ada},
     270    contributer = {pabuhr@plg},
     271    author      = {Ada12},
     272    title       = {Programming languages -- {Ada} ISO/IEC 8652:2012},
     273    edition     = {3rd},
     274    organization= {International Standard Organization},
     275    address     = {Geneva, Switzerland},
     276    year        = 2012,
     277    note        = {\href{https://www.iso.org/standard/61507.html}{https://\-www.iso.org/\-standard/\-61507.html}},
     278}
     279
     280@manual{Ada95:annotated,
     281    keywords    = {Ada},
     282    contributer = {pabuhr@plg},
     283    title       = {Annotated {A}da Reference Manual},
     284    edition     = {International Standard {ISO}/{IEC} {8652:1995(E)} with {COR.1:2000}},
     285    organization= {Intermetrics, Inc.},
     286    month       = dec,
     287    year        = 1995,
     288    note        = {Language and Standards Libraries}
     289}
     290
    247291@article{dim:ada,
    248292    keywords    = {Dimensional Analysis, Ada},
     
    256300    number      = 2,
    257301    pages       = {189-203},
     302}
     303
     304@article{Agrawal08,
     305    keywords    = {Adaptive scheduling, adversary, instantaneous parallelism, job scheduling, multiprocessing, multiprogramming, parallel computation, parallelism feedback, processor allocation, randomized algorithm, space sharing, span, thread scheduling, trim analysis, two-level scheduling, work, work-stealing},
     306    author      = {Agrawal, Kunal and Leiserson, Charles E. and He, Yuxiong and Hsu, Wen Jing},
     307    title       = {Adaptive Work-stealing with Parallelism Feedback},
     308    journal     = {ACM Trans. Comput. Syst.},
     309    issue_date  = {September 2008},
     310    volume      = {26},
     311    number      = {3},
     312    month       = sep,
     313    year        = {2008},
     314    pages       = {7:1-7:32},
     315    publisher   = {ACM},
     316    address     = {New York, NY, USA},
    258317}
    259318
     
    377436    year        = 2016,
    378437    note        = {\href{http://doc.akka.io/docs/akka/2.4/AkkaScala.pdf}{http://\-doc.akka.io/\-docs/\-akka/\-2.4/\-AkkaScala.pdf}},
     438}
     439
     440@misc{AkkaFuture,
     441    contributer = {pabuhr@plg},
     442    key         = {AkkaFuture},
     443    title       = {Akka Futures},
     444    author      = {{Lightbend}},
     445    howpublished= {\href{https://doc.akka.io/docs/akka/2.5/futures.html}{https://\-doc.akka.io/\-docs/\-akka/\-2.5/\-futures.html}},
     446    year        = 2022,
    379447}
    380448
     
    548616}
    549617
     618@inproceedings{Mitzenmacher98,
     619    author      = {Mitzenmacher, Michael},
     620    title       = {Analyses of Load Stealing Models Based on Differential Equations},
     621    organization= {Proceedings of the Tenth Annual ACM Symposium on Parallel Algorithms and Architectures},
     622    series      = {SPAA '98},
     623    year        = {1998},
     624    isbn        = {0-89791-989-0},
     625    location    = {Puerto Vallarta, Mexico},
     626    pages       = {212-221},
     627    publisher   = {ACM},
     628    address     = {New York, NY, USA},
     629}
     630
     631@inproceedings{Squillante91,
     632    author      = {Squillante, Mark S. and Nelson, Randolph D.},
     633    title       = {Analysis of Task Migration in Shared-memory Multiprocessor Scheduling},
     634    organization= {Proceedings of the 1991 ACM SIGMETRICS Conference on Measurement and Modeling of Computer Systems},
     635    series      = {SIGMETRICS '91},
     636    year        = {1991},
     637    isbn        = {0-89791-392-2},
     638    location    = {San Diego, California, USA},
     639    pages       = {143-155},
     640    publisher   = {ACM},
     641    address     = {New York, NY, USA},
     642}
     643
    550644@article{Sinha00,
    551645    author      = {Saurabh Sinha and Mary Jean Harrold},
     
    562656    author      = {Martin P. Robillard and Gail C. Murphy},
    563657    title       = {Analyzing Exception Flow in {J}ava Programs},
    564     booktitle   = {ESEC/FSE-7: Proceedings of the 7th European Software Engineering Conference held jointly
     658    organization= {ESEC/FSE-7: Proceedings of the 7th European Software Engineering Conference held jointly
    565659                   with the 7th ACM SIGSOFT International Symposium on Foundations of Software Engineering},
    566660    year        = 1999,
     
    604698    author      = {Henry Qin and Qian Li and Jacqueline Speiser and Peter Kraft and John Ousterhout},
    605699    title       = {Arachne: Core-Aware Thread Management},
    606     booktitle   = {13th {USENIX} Symp. on Oper. Sys. Design and Impl. ({OSDI} 18)},
     700    organization= {13th {USENIX} Symp. on Oper. Sys. Design and Impl. ({OSDI} 18)},
    607701    year        = {2018},
    608702    address     = {Carlsbad, CA},
     
    661755    author      = {Jaewoong Chung and Luke Yen and Stephan Diestelhorst and Martin Pohlack and Michael Hohmuth and David Christie and Dan Grossman},
    662756    title       = {ASF: AMD64 Extension for Lock-Free Data Structures and Transactional Memory},
    663     booktitle   = {Proceedings of the 2010 43rd Annual IEEE/ACM International Symposium on Microarchitecture},
     757    organization= {Proceedings of the 2010 43rd Annual IEEE/ACM International Symposium on Microarchitecture},
    664758    series      = {MICRO '43},
    665759    year        = 2010,
     
    682776}
    683777
     778@misc{AsyncAwait,
     779    contributer = {pabuhr@plg},
     780    key         = {AsyncAwait},
     781    title       = {Async Await},
     782    author      = {{WikipediA}},
     783    howpublished= {\href{https://en.wikipedia.org/wiki/Async/await}{https://\-en.wikipedia.org/\-wiki/\-Async/\-await}},
     784    year        = 2022,
     785}
     786
    684787@inproceedings{Krischer08,
    685788    keywords    = {exception handling, asynchronous, blocked tasks},
     
    687790    author      = {Roy Krischer and Peter A. Buhr},
    688791    title       = {Asynchronous Exception Propagation in Blocked Tasks},
    689     booktitle   = {4th International Workshop on Exception Handling (WEH.08)},
     792    organization= {4th International Workshop on Exception Handling (WEH.08)},
    690793    optorganization= {16th International Symposium on the Foundations of Software Engineering (FSE 16)},
    691794    address     = {Atlanta, U.S.A},
     
    759862    publisher   = {ACM},
    760863    address     = {New York, NY, USA},
     864}
     865
     866@techreport{Neill09,
     867    author      = {Daniel Neill and Adam Wierman},
     868    title       = {On the Benefits of Work Stealing in Shared-Memory Multiprocessors},
     869    institution = {Carnegie Mellon University},
     870    address     = {California Institute of Technology, Pasadena, CA, USA},
     871    note        = {\href{http://www.cs.cmu.edu/~acw/15740/paper.pdf}{http://\-www.cs.cmu.edu/\-$\sim$acw/\-15740/\-paper.pdf}, Accessed May 2014},
     872    year        = 2009,
    761873}
    762874
     
    9141026    year        = 2006,
    9151027    pages       = {1-21}
     1028}
     1029
     1030@inproceedings{Ding12,
     1031    keywords    = {fairness, multicore, time sharing, work stealing},
     1032    author      = {Ding, Xiaoning and Wang, Kaibo and Gibbons, Phillip B. and Zhang, Xiaodong},
     1033    title       = {BWS: Balanced Work Stealing for Time-sharing Multicores},
     1034    organization= {Proceedings of the 7th ACM European Conference on Computer Systems},
     1035    series      = {EuroSys '12},
     1036    year        = {2012},
     1037    location    = {Bern, Switzerland},
     1038    pages       = {365-378},
     1039    publisher   = {ACM},
     1040    address     = {New York, NY, USA},
    9161041}
    9171042
     
    20032128    author      = {Adya, Atul and Howell, Jon and Theimer, Marvin and Bolosky, William J. and Douceur, John R.},
    20042129    title       = {Cooperative Task Management Without Manual Stack Management},
    2005     booktitle   = {Proc. of the General Track USENIX Tech. Conf.},
     2130    organization= {Proc. of the General Track USENIX Tech. Conf.},
    20062131    series      = {ATEC '02},
    20072132    year        = {2002},
     
    21112236    year        = 2016,
    21122237    note        = {\href{http://dlang.org/spec/spec.html}{http://\-dlang.org/\-spec/\-spec.html}},
     2238}
     2239
     2240@article{Acar02,
     2241    author      = {Acar, Umut A. and Blelloch, Guy E. and Blumofe, Robert D.},
     2242    title       = {The Data Locality of Work Stealing},
     2243    journal     = {Theory of Computing Systems},
     2244    volume      = {35},
     2245    number      = {3},
     2246    year        = {2002},
     2247    publisher   = {Springer-Verlag},
     2248    pages       = {321-347},
    21132249}
    21142250
     
    23702506    editor      = {R. E. A. Mason},
    23712507    organization= {IFIP},
    2372     publisher = {North-Holland},
    2373     summary = {
     2508    publisher   = {North-Holland},
     2509    summary     = {
    23742510        Packages group related declarations or subprograms, and encapsulate
    23752511        data types.  Separate interfaces and bodies promotes information
     
    25982734    address     = {Waterview Corporate Center, 20 Waterview Boulevard, Parsippany, NJ 07054},
    25992735    year        = {1993}
     2736}
     2737
     2738@inproceedings{Chen14,
     2739    keywords    = {Core allocation, Multi-programmed, Work-stealing},
     2740    author      = {Chen, Quan and Zheng, Long and Guo, Minyi},
     2741    title       = {DWS: Demand-aware Work-Stealing in Multi-programmed Multi-core Architectures},
     2742    organization= {Proceedings of Programming Models and Applications on Multicores and Manycores},
     2743    series      = {PMAM'14},
     2744    year        = {2007},
     2745    location    = {Orlando, FL, USA},
     2746    pages       = {131:131-131:139},
     2747    articleno   = {131},
     2748    numpages    = {9},
     2749    publisher   = {ACM},
     2750    address     = {New York, NY, USA},
    26002751}
    26012752
     
    26312782    year        = 2003,
    26322783    pages       = {29-35},
     2784}
     2785
     2786@inproceedings{Hamidzadeh96,
     2787    keywords    = {processor scheduling, resource allocation, shared memory systems, average memory referencing delay},
     2788    author      = {Hamidzadeh, B. and Lilja, D.J.},
     2789    booktitle   = {Distributed Computing Systems, 1996., Proceedings of the 16th International Conference on},
     2790    title       = {Dynamic scheduling strategies for shared-memory multiprocessors},
     2791    year        = {1996},
     2792    month       = {May},
     2793    pages       = {208-215},
     2794}
     2795
     2796@article{Hendler06,
     2797    keywords    = {Concurrent programming; Load balancing; Work stealing; Lock-free; Data structures},
     2798    author      = {Hendler, Danny and Lev, Yossi and Moir, Mark and Shavit, Nir},
     2799    title       = {A dynamic-sized nonblocking work stealing deque},
     2800    journal     = {Distributed Computing},
     2801    volume      = {18},
     2802    number      = {3},
     2803    year        = {2006},
     2804    publisher   = {Springer-Verlag},
     2805    pages       = {189-207},
    26332806}
    26342807
     
    27342907}
    27352908
     2909@inproceedings{Blelloch04,
     2910    keywords    = {chip multiprocessors, multithreaded architectures, scheduling algorithms, shared cache},
     2911    author      = {Blelloch, Guy E. and Gibbons, Phillip B.},
     2912    title       = {Effectively Sharing a Cache Among Threads},
     2913    organization= {Proceedings of the Sixteenth Annual ACM Symposium on Parallelism in Algorithms and Architectures},
     2914    series      = {SPAA '04},
     2915    year        = {2004},
     2916    location    = {Barcelona, Spain},
     2917    pages       = {235-244},
     2918    publisher   = {ACM},
     2919    address     = {New York, NY, USA},
     2920}
     2921
    27362922@techreport{Habermann80,
    27372923    keywords    = {Ada, threads},
     
    28082994    title       = {Encapsulation and Inheritance in Object-Oriented Programming Languages},
    28092995    journal     = sigplan,
    2810     volume      = {21},    number = {11},
     2996    volume      = {21},
     2997    number      = {11},
    28112998    pages       = {38-45},
    2812     month       = nov, year = 1986,
     2999    month       = nov,
     3000    year        = 1986,
    28133001    comment     = {
    28143002        Client, child interfaces should be distinct.  Child interface
     
    28663054}
    28673055
     3056@inproceedings{Ribic14,
     3057    keywords    = {dvfs, energy efficiency, language runtimes, thread management, work stealing},
     3058    author      = {Ribic, Haris and Liu, Yu David},
     3059    title       = {Energy-efficient Work-stealing Language Runtimes},
     3060    organization= {Proceedings of the 19th International Conference on Architectural Support for Programming Languages and Operating Systems},
     3061    series      = {ASPLOS '14},
     3062    year        = {2014},
     3063    location    = {Salt Lake City, Utah, USA},
     3064    pages       = {513-528},
     3065    publisher   = {ACM},
     3066    address     = {New York, NY, USA},
     3067}
     3068
    28683069@manual{EPT,
    28693070    keywords    = {concurrency, light-weight threads},
     
    29033104    publisher   = {North Oxford Academic},
    29043105    year        = 1985
     3106}
     3107
     3108@article{Torrellas95,
     3109    author      = {J. Torrellas and A. Tucker and A. Gupta},
     3110    title       = {Evaluating the Performance of Cache-Affinity Scheduling in Shared-Memory Multiprocessors},
     3111    journal     = {Journal of Parallel and Distributed Computing},
     3112    volume      = {24},
     3113    number      = {2},
     3114    pages       = {139-151},
     3115    year        = {1995},
    29053116}
    29063117
     
    36143825    author      = {Robert Griesemer and Rob Pike and Ken Thompson},
    36153826    title       = {{Go} Programming Language},
     3827    address     = {Mountain View, CA, USA},
    36163828    organization= {Google},
    36173829    year        = 2009,
     
    37253937@article{Michael04a,
    37263938    keywords    = {Lock-free, synchronization, concurrent programming, memory management, multiprogramming, dynamic data structures},
     3939    contributer = {pabuhr@plg},
    37273940    author      = {Maged M. Michael},
    37283941    title       = {Hazard Pointers: Safe Memory Reclamation for Lock-Free Objects},
     
    37353948    publisher   = {IEEE Press},
    37363949    address     = {Piscataway, NJ, USA},
     3950}
     3951
     3952@inproceedings{Johansson02,
     3953    keywords    = {concurrent languages, erlang, garbage collection, message passing, runtime systems},
     3954    contributer = {pabuhr@plg},
     3955    author      = {Erik Johansson and Konstantinos Sagonas and Jesper Wilhelmsson},
     3956    title       = {Heap Architectures for Concurrent Languages Using Message Passing},
     3957    year        = {2002},
     3958    isbn        = {1581135394},
     3959    publisher   = {ACM},
     3960    address     = {New York, NY, USA},
     3961    organization= {Proceedings of the 3rd International Symposium on Memory Management},
     3962    pages       = {88-99},
     3963    location    = {Berlin, Germany},
    37373964}
    37383965
     
    39174144    year        = {1994},
    39184145    pages       = {64-69},
     4146}
     4147
     4148@inproceedings{Halstead84,
     4149    author      = {Halstead,Jr., Robert H.},
     4150    title       = {Implementation of Multilisp: Lisp on a Multiprocessor},
     4151    organization= {Proceedings of the 1984 ACM Symposium on LISP and Functional Programming},
     4152    series      = {LFP '84},
     4153    year        = {1984},
     4154    location    = {Austin, Texas, USA},
     4155    pages       = {9-17},
     4156    publisher   = {ACM},
     4157    address     = {New York, NY, USA},
    39194158}
    39204159
     
    46954934    contributer = {pabuhr@plg},
    46964935    author      = {Lua},
    4697     title       = {Lua 5.3 Reference Manual},
    4698     address     = {\href{https://www.lua.org/manual/5.3}{https://\-www.lua.org/\-manual/\-5.3}},
    4699     year        = 2018,
     4936    title       = {Lua 5.4 Reference Manual},
     4937    organization= {Pontifical Catholic University},
     4938    address     = {\href{https://www.lua.org/manual/5.4}{https://\-www.lua.org/\-manual/\-5.4}},
     4939    year        = 2020,
    47004940}
    47014941
     
    52775517        Programming Language},
    52785518    year        = 1980,
    5279     month       = dec, pages = {139-145},
     5519    month       = dec,
     5520    pages       = {139-145},
    52805521    note        = {SIGPLAN Notices, v. 15, n. 11},
    52815522    abstract    = {
     
    53985639    year        = 2005,
    53995640    pages       = {146-196},
     5641    publisher   = {ACM},
     5642    address     = {New York, NY, USA},
     5643}
     5644
     5645@inproceedings{Hendler02,
     5646    author      = {Hendler, Danny and Shavit, Nir},
     5647    title       = {Non-blocking Steal-half Work Queues},
     5648    organization= {Proceedings of the Twenty-first Annual Symposium on Principles of Distributed Computing},
     5649    series      = {PODC '02},
     5650    year        = {2002},
     5651    location    = {Monterey, California},
     5652    pages       = {280-289},
    54005653    publisher   = {ACM},
    54015654    address     = {New York, NY, USA},
     
    56465899}
    56475900
     5901@misc{OpenTelemetry,
     5902    contributer = {pabuhr@plg},
     5903    key         = {OpenTelemetry},
     5904    title       = {OpenTelemetry},
     5905    author      = {{Asynkron AB}},
     5906    howpublished= {\href{https://proto.actor/docs/tracing}{https://\-proto.actor/\-docs/\-tracing}},
     5907    year        = 2022,
     5908}
     5909
    56485910@inproceedings{Krebbers14,
    56495911    keywords    = {c formalization},
     
    58836145}
    58846146
     6147@article{Nigro21,
     6148    keywords    = {Actors, Asynchronous messages, Reflective control on message passing, Lock-free parallel computing, Java, Scalable multi-agent systems, Parallel matrix multiplication, Iterated Prisoner's Dilemma},
     6149    contributer = {pabuhr@plg},
     6150    author      = {Libero Nigro},
     6151    title       = {Parallel Theatre: An actor framework in {Java} for high performance computing},
     6152    journal     = {Simulation Modelling Practice and Theory},
     6153    volume      = {106},
     6154    number      = {102189},
     6155    year        = {2021},
     6156}
     6157
    58856158@incollection{Stroustrup96,
    58866159    keywords    = {concurrency, C++},
     
    59176190    journal     = ieeese,
    59186191    year        = 1984,
    5919     month       = sep, volume = "SE-10", number = 5, pages = {528-543},
     6192    month       = sep,
     6193    volume      = "SE-10",
     6194    number      = 5,
     6195    pages       = {528-543},
    59206196    abstract    = {
    59216197        Parameterized programming is a powerful technique for the reliable
     
    59496225    booktitle   = {USENIX {C}{\kern-.1em\hbox{\large\texttt{+\kern-.25em+}}} Conference},
    59506226    organization= {USENIX Association},
    5951     year        = 1988, pages = {1-18}
     6227    year        = 1988,
     6228    pages       = {1-18}
    59526229}
    59536230
     
    60376314}
    60386315
     6316@incollection{Kazempour08,
     6317    keywords    = {multicore processors; cache affinity; performance evaluation; scheduling},
     6318    author      = {Kazempour, Vahid and Fedorova, Alexandra and Alagheband, Pouya},
     6319    title       = {Performance Implications of Cache Affinity on Multicore Processors},
     6320    organization= {Euro-Par 2008 -- Parallel Processing},
     6321    series      = {Lecture Notes in Computer Science},
     6322    editor      = {Luque, Emilio and Margalef, Tomas and Benitez, Domingo},
     6323    year        = {2008},
     6324    volume      = {5168},
     6325    pages       = {151-161},
     6326    publisher   = {Springer Berlin Heidelberg},
     6327}
     6328
     6329@article{Anderson89,
     6330    keywords    = {data structures, multiprocessing systems, operating systems (computers), performance evaluation, critical resource waiting},
     6331    author      = {Anderson, T.E. and Lazowska, E.D. and Levy, H.M.},
     6332    journal     = {Computers, IEEE Transactions on},
     6333    title       = {The Performance Implications of Thread Management Alternatives for Shared-Memory Multiprocessors},
     6334    year        = {1989},
     6335    month       = {Dec},
     6336    volume      = {38},
     6337    number      = {12},
     6338    pages       = {1631-1644},
     6339}
     6340
    60396341@article{Anderson90,
    60406342    keywords    = {spin locks, back off, performance},
     
    60486350    number      = 1,
    60496351    pages       = {6-16},
     6352}
     6353
     6354@article{Blumofe98,
     6355    author      = {Blumofe, Robert D. and Papadopoulos, Dionisios},
     6356    title       = {The Performance of Work Stealing in Multiprogrammed Environments (Extended Abstract)},
     6357    journal     = {SIGMETRICS Perform. Eval. Rev.},
     6358    volume      = {26},
     6359    number      = {1},
     6360    month       = jun,
     6361    year        = {1998},
     6362    issn        = {0163-5999},
     6363    pages       = {266-267},
     6364    publisher   = {ACM},
     6365    address     = {New York, NY, USA},
    60506366}
    60516367
     
    67607076}
    67617077
    6762 @manual{Ada95,
    6763     keywords    = {Ada},
    6764     contributer = {pabuhr@plg},
    6765     title       = {{A}da Reference Manual},
    6766     edition     = {International Standard {ISO}/{IEC} {8652:1995(E)} with {COR.1:2000}},
    6767     organization= {Intermetrics, Inc.},
    6768     month       = dec,
    6769     year        = 1995,
    6770     note        = {Language and Standards Libraries}
    6771 }
    6772 
    6773 @manual{Ada12,
    6774     keywords    = {ISO/IEC Ada},
    6775     contributer = {pabuhr@plg},
    6776     author      = {Ada12},
    6777     title       = {Programming languages -- {Ada} ISO/IEC 8652:2012},
    6778     edition     = {3rd},
    6779     organization= {International Standard Organization},
    6780     address     = {Geneva, Switzerland},
    6781     year        = 2012,
    6782     note        = {\href{https://www.iso.org/standard/61507.html}{https://\-www.iso.org/\-standard/\-61507.html}},
    6783 }
    6784 
    6785 @manual{Ada95:annotated,
    6786     keywords    = {Ada},
    6787     contributer = {pabuhr@plg},
    6788     title       = {Annotated {A}da Reference Manual},
    6789     edition     = {International Standard {ISO}/{IEC} {8652:1995(E)} with {COR.1:2000}},
    6790     organization = {Intermetrics, Inc.},
    6791     month       = dec,
    6792     year        = 1995,
    6793     note        = {Language and Standards Libraries}
     7078@inproceedings{Bacon03,
     7079    keywords    = {utilization, real-time scheduling, read barrier, defragmentation},
     7080    contributer = {pabuhr@plg},
     7081    author      = {David F. Bacon and Perry Cheng and V. T. Rajan},
     7082    title       = {A Real-Time Garbage Collector with Low Overhead and Consistent Utilization},
     7083    year        = {2003},
     7084    organization= {Proceedings of the 30th ACM SIGPLAN-SIGACT Symposium on Principles of Programming Languages},
     7085    publisher   = {ACM},
     7086    address     = {New York, NY, USA},
     7087    pages       = {285-298},
     7088    location    = {New Orleans, Louisiana, USA},
    67947089}
    67957090
     
    69277222    journal     = sigplan,
    69287223    year        = 1991,
    6929     month       = oct, volume = 26, number = 10, pages = {29-43},
     7224    month       = oct,
     7225    volume      = 26,
     7226    number      = 10,
     7227    pages       = {29-43},
    69307228    abstract    = {
    69317229        {\tt lcc} is a new retargetable compiler for ANSI C.  Versions for
     
    70177315    publisher   = {ACM},
    70187316    address     = {New York, NY, USA},
    7019     booktitle   = {Proceedings of the 4th International Workshop on Programming Based on Actors Agents \& Decentralized Control},
     7317    organization= {Proceedings of the 4th International Workshop on Programming Based on Actors Agents \& Decentralized Control},
    70207318    pages       = {67-80},
    70217319    numpages    = {14},
     
    70497347}
    70507348
     7349@article{Nickolls08,
     7350    author      = {Nickolls, John and Buck, Ian and Garland, Michael and Skadron, Kevin},
     7351    title       = {Scalable Parallel Programming with CUDA},
     7352    journal     = {Queue},
     7353    volume      = {6},
     7354    number      = {2},
     7355    month       = mar,
     7356    year        = 2008,
     7357    pages       = {40-53},
     7358    publisher   = {ACM},
     7359    address     = {New York, NY, USA},
     7360}
     7361
    70517362@article{Anderson92,
    70527363    keywords    = {light-weight tasks},
     
    70607371    year        = 1992,
    70617372    pages       = {53-79},
     7373}
     7374
     7375@article{Blumofe99,
     7376    keywords    = {critical-path length, multiprocessor, multithreading, randomized algorithm, thread scheduling, work stealing},
     7377    author      = {Blumofe, Robert D. and Leiserson, Charles E.},
     7378    title       = {Scheduling Multithreaded Computations by Work Stealing},
     7379    journal     = {Journal of the ACM},
     7380    volume      = {46},
     7381    number      = {5},
     7382    month       = sep,
     7383    year        = {1999},
     7384    pages       = {720-748},
     7385    publisher   = {ACM},
     7386    address     = {New York, NY, USA},
     7387}
     7388
     7389@inproceedings{Acar13,
     7390    keywords    = {dynamic load balancing, nested parallelism, work stealing},
     7391    author      = {Acar, Umut A. and Chargueraud, Arthur and Rainey, Mike},
     7392    title       = {Scheduling Parallel Programs by Work Stealing with Private Deques},
     7393    organization= {Proceedings of the 18th ACM SIGPLAN Symposium on Principles and Practice of Parallel Programming},
     7394    series      = {PPoPP '13},
     7395    year        = {2013},
     7396    location    = {Shenzhen, China},
     7397    pages       = {219-228},
     7398    publisher   = {ACM},
     7399    address     = {New York, NY, USA},
     7400}
     7401
     7402@inproceedings{Chen07,
     7403    keywords    = {chip multiprocessors, constructive cache sharing, parallel depth first, scheduling algorithms, thread granularity, work stealing, working set profiling},
     7404    author      = {Chen, Shimin and Gibbons, Phillip B. and Kozuch, Michael and Liaskovitis, Vasileios and Ailamaki, Anastassia and Blelloch, Guy E. and Falsafi, Babak and Fix, Limor and Hardavellas, Nikos and Mowry, Todd C. and Wilkerson, Chris},
     7405    title       = {Scheduling Threads for Constructive Cache Sharing on CMPs},
     7406    organization= {Proceedings of the Nineteenth Annual ACM Symposium on Parallel Algorithms and Architectures},
     7407    series      = {SPAA '07},
     7408    year        = {2007},
     7409    location    = {San Diego, California, USA},
     7410    pages       = {105-115},
     7411    numpages    = {11},
     7412    publisher   = {ACM},
     7413    address     = {New York, NY, USA},
    70627414}
    70637415
     
    71507502    publisher   = {Morgan \& Claypool},
    71517503    year        = 2013,
    7152 }
    7153 
    7154 @article{Nickolls08,
    7155     author      = {Nickolls, John and Buck, Ian and Garland, Michael and Skadron, Kevin},
    7156     title       = {Scalable Parallel Programming with CUDA},
    7157     journal     = {Queue},
    7158     volume      = {6},
    7159     number      = {2},
    7160     month       = mar,
    7161     year        = 2008,
    7162     pages       = {40-53},
    7163     publisher   = {ACM},
    7164     address     = {New York, NY, USA},
    71657504}
    71667505
     
    78338172}
    78348173
     8174@article{Arora01,
     8175    author      = {Arora, N. S. and Blumofe, R. D. and Plaxton, C. G.},
     8176    title       = {Thread Scheduling for Multiprogrammed Multiprocessors},
     8177    journal     = {Theory of Computing Systems},
     8178    year        = {2001},
     8179    volume      = {34},
     8180    number      = {2},
     8181    pages       = {115-144},
     8182    publisher   = {Springer-Verlag},
     8183}
     8184
    78358185@article{Boehm05,
    78368186    keywords    = {concurrency, C++},
     
    80608410}
    80618411
     8412@misc{AkkaBecome,
     8413    contributer = {pabuhr@plg},
     8414    key         = {AkkaBecome},
     8415    title       = {Typed Actors},
     8416    author      = {{Lightbend}},
     8417    howpublished= {\href{https://doc.akka.io/docs/akka/2.5/typed-actors.html}{https://\-doc.akka.io/\-docs/\-akka/\-2.5/\-typed-actors.html}},
     8418    year        = 2022,
     8419}
     8420
    80628421@article{concatenation,
    80638422    keywords    = {record concatenation, isa},
     
    81378496    author      = {Carl Hewitt and Peter Bishop and Richard Steiger},
    81388497    title       = {A Universal Modular {ACTOR} Formalism for Artificial Intelligence},
    8139     booktitle   = {Proceedings of the 3rd International Joint Conference on Artificial Intelligence},
     8498    organization= {Proceedings of the 3rd International Joint Conference on Artificial Intelligence},
    81408499    address     = {Standford, California, U.S.A.},
    81418500    pages       = {235-245},
     8501    location    = {Stanford, USA},
     8502    series      = {IJCAI'73},
    81428503    month       = aug,
    81438504    year        = 1973,
     
    81718532@article{Karsten20,
    81728533    author      = {Karsten, Martin and Barghi, Saman},
    8173     title       = {{User-level Threading: Have Your Cake and Eat It Too}},
     8534    title       = {User-level Threading: Have Your Cake and Eat It Too},
    81748535    year        = {2020},
    81758536    issue_date  = {March 2020},
     
    81968557}
    81978558
     8559@article{Squillante93,
     8560    keywords    = {buffer storage, performance evaluation, queueing theory, scheduling, shared memory systems, processor-cache affinity},
     8561    author      = {Squillante, M.S. and Lazowska, E.D.},
     8562    title       = {Using Processor-Cache Affinity Information in Shared-Memory Multiprocessor Scheduling},
     8563    journal     = {Parallel and Distributed Systems, IEEE Transactions on},
     8564    year        = {1993},
     8565    month       = {Feb},
     8566    volume      = {4},
     8567    number      = {2},
     8568    pages       = {131-143},
     8569}
     8570
    81988571@article{delegation,
    81998572    keywords    = {delegation, inheritance, actors},
     
    83458718    year        = 2003,
    83468719    pages       = {19-24},
     8720}
     8721
     8722@inproceedings{Saman18,
     8723    keywords    = {actors, scheduling, NUMA, locality},
     8724    contributer = {pabuhr@plg},
     8725    author      = {Saman Barghi and Martin Karsten},
     8726    organization= {2018 IEEE International Parallel and Distributed Processing Symposium (IPDPS)},
     8727    title       = {Work-Stealing, Locality-Aware Actor Scheduling},
     8728    year        = {2018},
     8729    address     = {Vancouver, BC, Canada},
     8730    pages       = {484-494},
     8731}
     8732
     8733@article{Wimmer13,
     8734    keywords    = {priorities, scheduler hints, strategies, work-stealing},
     8735    author      = {Wimmer, Martin and Cederman, Daniel and Tr\"{a}ff, Jesper Larsson and Tsigas, Philippas},
     8736    title       = {Work-stealing with Configurable Scheduling Strategies},
     8737    journal     = {SIGPLAN Not.},
     8738    issue_date  = {August 2013},
     8739    volume      = {48},
     8740    number      = {8},
     8741    month       = feb,
     8742    year        = {2013},
     8743    issn        = {0362-1340},
     8744    pages       = {315-316},
     8745    publisher   = {ACM},
     8746    address     = {New York, NY, USA},
    83478747}
    83488748
  • driver/cfa.cc

    r1180175 r640b3df  
    1010// Created On       : Tue Aug 20 13:44:49 2002
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Wed Jul 14 21:55:12 2021
    13 // Update Count     : 467
     12// Last Modified On : Tue Feb 14 22:46:38 2023
     13// Update Count     : 470
    1414//
    1515
     
    444444
    445445        args[nargs++] = "-fexceptions";                                         // add exception flags (unconditionally)
     446        args[nargs++] = "-D_GNU_SOURCE";                                        // force gnu libraries
    446447
    447448        // add flags based on the type of compile
  • libcfa/src/bitmanip.hfa

    r1180175 r640b3df  
    1111// Created On       : Sat Mar 14 18:12:27 2020
    1212// Last Modified By : Peter A. Buhr
    13 // Last Modified On : Sat Oct  8 08:28:15 2022
    14 // Update Count     : 142
     13// Last Modified On : Mon Jan  9 09:02:43 2023
     14// Update Count     : 144
    1515//
    1616
    1717#pragma once
     18
     19#include "bits/debug.hfa"                                                               // verify
    1820
    1921// Reference: Bit Twiddling Hacks: http://graphics.stanford.edu/%7Eseander/bithacks.html#CountBitsSetNaive
  • libcfa/src/concurrency/clib/cfathread.cfa

    r1180175 r640b3df  
    1616// #define EPOLL_FOR_SOCKETS
    1717
     18#include <sys/socket.h> // first include because of anonymous types __SOCKADDR_ARG, __CONST_SOCKADDR_ARG
     19#include <string.h>
     20#include <errno.h>
     21
    1822#include "fstream.hfa"
    1923#include "locks.hfa"
     
    2630#include "cfathread.h"
    2731
    28 extern "C" {
    29                 #include <string.h>
    30                 #include <errno.h>
    31 }
    32 
    3332extern void ?{}(processor &, const char[], cluster &, thread$ *);
    3433extern "C" {
    35       extern void __cfactx_invoke_thread(void (*main)(void *), void * this);
    36         extern int accept4(int sockfd, struct sockaddr *addr, socklen_t *addrlen, int flags);
     34        extern void __cfactx_invoke_thread(void (*main)(void *), void * this);
    3735}
    3836
     
    472470}
    473471
     472#include <unistd.h>
     473
    474474#include <iofwd.hfa>
    475475
    476476extern "C" {
    477         #include <unistd.h>
    478         #include <sys/types.h>
    479         #include <sys/socket.h>
    480 
    481477        //--------------------
    482478        // IO operations
     
    488484                , protocol);
    489485        }
    490         int cfathread_bind(int socket, const struct sockaddr *address, socklen_t address_len) {
     486        int cfathread_bind(int socket, __CONST_SOCKADDR_ARG address, socklen_t address_len) {
    491487                return bind(socket, address, address_len);
    492488        }
     
    496492        }
    497493
    498         int cfathread_accept(int socket, struct sockaddr *restrict address, socklen_t *restrict address_len) {
     494        int cfathread_accept(int socket, __SOCKADDR_ARG address, socklen_t *restrict address_len) {
    499495                #if defined(EPOLL_FOR_SOCKETS)
    500496                        int ret;
     
    513509        }
    514510
    515         int cfathread_connect(int socket, const struct sockaddr *address, socklen_t address_len) {
     511        int cfathread_connect(int socket, __CONST_SOCKADDR_ARG address, socklen_t address_len) {
    516512                #if defined(EPOLL_FOR_SOCKETS)
    517513                        int ret;
  • libcfa/src/concurrency/clib/cfathread.h

    r1180175 r640b3df  
    99// Author           : Thierry Delisle
    1010// Created On       : Tue Sep 22 15:31:20 2020
    11 // Last Modified By :
    12 // Last Modified On :
    13 // Update Count     :
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Thu Feb 16 12:00:32 2023
     13// Update Count     : 5
    1414//
    1515
    1616#if defined(__cforall) || defined(__cplusplus)
     17#include <sys/socket.h> // first include because of anonymous types __SOCKADDR_ARG, __CONST_SOCKADDR_ARG
     18#include <unistd.h>
     19#include <errno.h>
     20
    1721extern "C" {
    1822#endif
    19         #include <asm/types.h>
    20         #include <errno.h>
    21         #include <unistd.h>
    22 
    23 
    2423        //--------------------
    2524        // Basic types
     
    7372        } cfathread_mutexattr_t;
    7473        typedef struct cfathread_mutex * cfathread_mutex_t;
    75         int cfathread_mutex_init(cfathread_mutex_t *restrict mut, const cfathread_mutexattr_t *restrict attr) __attribute__((nonnull (1)));
     74        int cfathread_mutex_init(cfathread_mutex_t * restrict mut, const cfathread_mutexattr_t * restrict attr) __attribute__((nonnull (1)));
    7675        int cfathread_mutex_destroy(cfathread_mutex_t *mut) __attribute__((nonnull (1)));
    7776        int cfathread_mutex_lock(cfathread_mutex_t *mut) __attribute__((nonnull (1)));
     
    9190        //--------------------
    9291        // IO operations
    93         struct sockaddr;
    94         struct msghdr;
    9592        int cfathread_socket(int domain, int type, int protocol);
    96         int cfathread_bind(int socket, const struct sockaddr *address, socklen_t address_len);
     93        int cfathread_bind(int socket, __CONST_SOCKADDR_ARG address, socklen_t address_len);
    9794        int cfathread_listen(int socket, int backlog);
    98         int cfathread_accept(int socket, struct sockaddr *restrict address, socklen_t *restrict address_len);
    99         int cfathread_connect(int socket, const struct sockaddr *address, socklen_t address_len);
     95        int cfathread_accept(int socket, __SOCKADDR_ARG address, socklen_t * restrict address_len);
     96        int cfathread_connect(int socket, __CONST_SOCKADDR_ARG address, socklen_t address_len);
    10097        int cfathread_dup(int fildes);
    10198        int cfathread_close(int fildes);
  • libcfa/src/concurrency/coroutine.cfa

    r1180175 r640b3df  
    1010// Created On       : Mon Nov 28 12:27:26 2016
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Tue Dec 15 12:06:04 2020
    13 // Update Count     : 23
     12// Last Modified On : Thu Feb 16 15:34:46 2023
     13// Update Count     : 24
    1414//
    1515
    1616#define __cforall_thread__
    17 #define _GNU_SOURCE
    1817
    1918#include "coroutine.hfa"
  • libcfa/src/concurrency/io.cfa

    r1180175 r640b3df  
    1515
    1616#define __cforall_thread__
    17 #define _GNU_SOURCE
    1817
    1918#if defined(__CFA_DEBUG__)
  • libcfa/src/concurrency/io/call.cfa.in

    r1180175 r640b3df  
    3131Prelude = """#define __cforall_thread__
    3232
     33#include <sys/socket.h> // first include because of anonymous types __SOCKADDR_ARG, __CONST_SOCKADDR_ARG
     34#include <unistd.h>
     35#include <errno.h>
     36#include <time.hfa>
     37
    3338#include "bits/defs.hfa"
    3439#include "kernel.hfa"
     
    4348        #include <assert.h>
    4449        #include <stdint.h>
    45         #include <errno.h>
    4650        #include <linux/io_uring.h>
    47 
    4851        #include "kernel/fwd.hfa"
    4952
     
    8285// I/O Forwards
    8386//=============================================================================================
    84 #include <time.hfa>
    85 
    86 // Some forward declarations
    87 #include <errno.h>
    88 #include <unistd.h>
    8987
    9088extern "C" {
    91         #include <asm/types.h>
    92         #include <sys/socket.h>
    93         #include <sys/syscall.h>
    94 
    9589#if defined(CFA_HAVE_PREADV2)
    9690        struct iovec;
     
    118112        extern ssize_t send(int sockfd, const void *buf, size_t len, int flags);
    119113        extern ssize_t recv(int sockfd, void *buf, size_t len, int flags);
    120         extern int accept4(int sockfd, struct sockaddr *addr, socklen_t *addrlen, int flags);
    121         extern int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
    122114
    123115        extern int fallocate(int fd, int mode, off_t offset, off_t len);
     
    292284        }),
    293285        # CFA_HAVE_IORING_OP_ACCEPT
    294         Call('ACCEPT', 'int accept4(int sockfd, struct sockaddr *addr, socklen_t *addrlen, int flags)', {
    295                 'fd': 'sockfd',
    296                 'addr': '(uintptr_t)addr',
     286        Call('ACCEPT', 'int accept4(int sockfd, __SOCKADDR_ARG addr, socklen_t * restrict addrlen, int flags)', {
     287                'fd': 'sockfd',
     288                'addr': '(uintptr_t)&addr',
    297289                'addr2': '(uintptr_t)addrlen',
    298290                'accept_flags': 'flags'
    299291        }),
    300292        # CFA_HAVE_IORING_OP_CONNECT
    301         Call('CONNECT', 'int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen)', {
    302                 'fd': 'sockfd',
    303                 'addr': '(uintptr_t)addr',
     293        Call('CONNECT', 'int connect(int sockfd, __CONST_SOCKADDR_ARG addr, socklen_t addrlen)', {
     294                'fd': 'sockfd',
     295                'addr': '(uintptr_t)&addr',
    304296                'off': 'addrlen'
    305297        }),
  • libcfa/src/concurrency/io/setup.cfa

    r1180175 r640b3df  
    1515
    1616#define __cforall_thread__
    17 #define _GNU_SOURCE
    1817
    1918#if defined(__CFA_DEBUG__)
  • libcfa/src/concurrency/iofwd.hfa

    r1180175 r640b3df  
    1616#pragma once
    1717
     18#include <sys/socket.h> // first include because of anonymous types __SOCKADDR_ARG, __CONST_SOCKADDR_ARG
    1819#include <unistd.h>
     20
    1921extern "C" {
    2022        #include <asm/types.h>
     
    5355struct iovec;
    5456struct msghdr;
    55 struct sockaddr;
    5657struct statx;
    5758struct epoll_event;
     
    100101extern ssize_t cfa_send(int sockfd, const void *buf, size_t len, int flags, __u64 submit_flags);
    101102extern ssize_t cfa_recv(int sockfd, void *buf, size_t len, int flags, __u64 submit_flags);
    102 extern int cfa_accept4(int sockfd, struct sockaddr *addr, socklen_t *addrlen, int flags, __u64 submit_flags);
    103 extern int cfa_connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen, __u64 submit_flags);
     103extern int cfa_accept4(int sockfd, __SOCKADDR_ARG addr, socklen_t * restrict addrlen, int flags, __u64 submit_flags);
     104extern int cfa_connect(int sockfd, __CONST_SOCKADDR_ARG addr, socklen_t addrlen, __u64 submit_flags);
    104105extern int cfa_fallocate(int fd, int mode, off_t offset, off_t len, __u64 submit_flags);
    105106extern int cfa_posix_fadvise(int fd, off_t offset, off_t len, int advice, __u64 submit_flags);
     
    133134extern void async_send(io_future_t & future, int sockfd, const void *buf, size_t len, int flags, __u64 submit_flags);
    134135extern void async_recv(io_future_t & future, int sockfd, void *buf, size_t len, int flags, __u64 submit_flags);
    135 extern void async_accept4(io_future_t & future, int sockfd, struct sockaddr *addr, socklen_t *addrlen, int flags, __u64 submit_flags);
    136 extern void async_connect(io_future_t & future, int sockfd, const struct sockaddr *addr, socklen_t addrlen, __u64 submit_flags);
     136extern void async_accept4(io_future_t & future, int sockfd, __SOCKADDR_ARG addr, socklen_t * restrict addrlen, int flags, __u64 submit_flags);
     137extern void async_connect(io_future_t & future, int sockfd, __CONST_SOCKADDR_ARG addr, socklen_t addrlen, __u64 submit_flags);
    137138extern void async_fallocate(io_future_t & future, int fd, int mode, off_t offset, off_t len, __u64 submit_flags);
    138139extern void async_posix_fadvise(io_future_t & future, int fd, off_t offset, off_t len, int advice, __u64 submit_flags);
  • libcfa/src/concurrency/kernel.cfa

    r1180175 r640b3df  
    1010// Created On       : Tue Jan 17 12:27:26 2017
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Wed Nov 30 18:14:08 2022
    13 // Update Count     : 76
     12// Last Modified On : Mon Jan  9 08:42:05 2023
     13// Update Count     : 77
    1414//
    1515
    1616#define __cforall_thread__
    17 #define _GNU_SOURCE
    1817
    1918// #define __CFA_DEBUG_PRINT_RUNTIME_CORE__
  • libcfa/src/concurrency/kernel/cluster.cfa

    r1180175 r640b3df  
    1515
    1616#define __cforall_thread__
    17 #define _GNU_SOURCE
    1817
    1918#include "bits/defs.hfa"
  • libcfa/src/concurrency/kernel/startup.cfa

    r1180175 r640b3df  
    1515
    1616#define __cforall_thread__
    17 #define _GNU_SOURCE
    1817
    1918// #define __CFA_DEBUG_PRINT_RUNTIME_CORE__
    2019
    2120// C Includes
    22 #include <errno.h>                                      // errno
     21#include <errno.h>                                                                              // errno
    2322#include <signal.h>
    24 #include <string.h>                                     // strerror
    25 #include <unistd.h>                                     // sysconf
    26 
     23#include <string.h>                                                                             // strerror
     24#include <unistd.h>
     25#include <limits.h>                                                                             // PTHREAD_STACK_MIN
    2726extern "C" {
    28         #include <limits.h>                             // PTHREAD_STACK_MIN
    29         #include <unistd.h>                             // syscall
    30         #include <sys/eventfd.h>                        // eventfd
    31         #include <sys/mman.h>                           // mprotect
    32         #include <sys/resource.h>                       // getrlimit
     27        #include <sys/eventfd.h>                                                        // eventfd
     28        #include <sys/mman.h>                                                           // mprotect
     29        #include <sys/resource.h>                                                       // getrlimit
    3330}
    3431
  • libcfa/src/concurrency/locks.cfa

    r1180175 r640b3df  
    1616
    1717#define __cforall_thread__
    18 #define _GNU_SOURCE
    1918
    2019#include "locks.hfa"
  • libcfa/src/concurrency/monitor.cfa

    r1180175 r640b3df  
    1010// Created On       : Thd Feb 23 12:27:26 2017
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Wed Dec  4 07:55:14 2019
    13 // Update Count     : 10
     12// Last Modified On : Sun Feb 19 17:00:59 2023
     13// Update Count     : 12
    1414//
    1515
    1616#define __cforall_thread__
    17 #define _GNU_SOURCE
    1817
    1918#include "monitor.hfa"
  • libcfa/src/concurrency/mutex.cfa

    r1180175 r640b3df  
    1212// Created On       : Fri May 25 01:37:11 2018
    1313// Last Modified By : Peter A. Buhr
    14 // Last Modified On : Wed Dec  4 09:16:39 2019
    15 // Update Count     : 1
     14// Last Modified On : Sun Feb 19 17:01:36 2023
     15// Update Count     : 3
    1616//
    1717
    1818#define __cforall_thread__
    19 #define _GNU_SOURCE
    2019
    2120#include "mutex.hfa"
  • libcfa/src/concurrency/preemption.cfa

    r1180175 r640b3df  
    1010// Created On       : Mon Jun 5 14:20:42 2017
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Feb 17 11:18:57 2022
    13 // Update Count     : 59
     12// Last Modified On : Mon Jan  9 08:42:59 2023
     13// Update Count     : 60
    1414//
    1515
    1616#define __cforall_thread__
    17 #define _GNU_SOURCE
    1817
    1918// #define __CFA_DEBUG_PRINT_PREEMPTION__
  • libcfa/src/concurrency/pthread.cfa

    r1180175 r640b3df  
    1515
    1616#define __cforall_thread__
    17 #define _GNU_SOURCE
    1817
    1918#include <signal.h>
     
    3534struct pthread_values{
    3635        inline Seqable;
    37         void* value;
     36        void * value;
    3837        bool in_use;
    3938};
     
    5150struct pthread_keys {
    5251        bool in_use;
    53         void (*destructor)( void * );
     52        void (* destructor)( void * );
    5453        Sequence(pthread_values) threads;
    5554};
    5655
    57 static void ?{}(pthread_keys& k){
     56static void ?{}(pthread_keys& k) {
    5857        k.threads{};
    5958}
     
    6261static pthread_keys cfa_pthread_keys_storage[PTHREAD_KEYS_MAX] __attribute__((aligned (16)));
    6362
    64 static void init_pthread_storage(){
    65         for (int i = 0; i < PTHREAD_KEYS_MAX; i++){
     63static void init_pthread_storage() {
     64        for ( int i = 0; i < PTHREAD_KEYS_MAX; i++ ) {
    6665                cfa_pthread_keys_storage[i]{};
    6766        }
     
    9695
    9796/* condvar helper routines */
    98 static void init(pthread_cond_t* pcond){
     97static void init(pthread_cond_t * pcond) {
    9998        static_assert(sizeof(pthread_cond_t) >= sizeof(cfa2pthr_cond_var_t),"sizeof(pthread_t) < sizeof(cfa2pthr_cond_var_t)");
    100         cfa2pthr_cond_var_t* _cond = (cfa2pthr_cond_var_t*)pcond;
     99        cfa2pthr_cond_var_t * _cond = (cfa2pthr_cond_var_t *)pcond;
    101100        ?{}(*_cond);
    102101}
    103102
    104 static cfa2pthr_cond_var_t* get(pthread_cond_t* pcond){
     103static cfa2pthr_cond_var_t * get(pthread_cond_t * pcond) {
    105104        static_assert(sizeof(pthread_cond_t) >= sizeof(cfa2pthr_cond_var_t),"sizeof(pthread_t) < sizeof(cfa2pthr_cond_var_t)");
    106         return (cfa2pthr_cond_var_t*)pcond;
    107 }
    108 
    109 static void destroy(pthread_cond_t* cond){
     105        return (cfa2pthr_cond_var_t *)pcond;
     106}
     107
     108static void destroy(pthread_cond_t * cond) {
    110109        static_assert(sizeof(pthread_cond_t) >= sizeof(cfa2pthr_cond_var_t),"sizeof(pthread_t) < sizeof(cfa2pthr_cond_var_t)");
    111110        ^?{}(*get(cond));
     
    116115
    117116/* mutex helper routines */
    118 static void mutex_check(pthread_mutex_t* t){
     117static void mutex_check(pthread_mutex_t * t) {
    119118        // Use double check to improve performance.
    120119        // Check is safe on x86; volatile prevents compiler reordering
    121         volatile pthread_mutex_t *const mutex_ = t;
     120        volatile pthread_mutex_t * const mutex_ = t;
    122121
    123122        // SKULLDUGGERY: not a portable way to access the kind field, /usr/include/x86_64-linux-gnu/bits/pthreadtypes.h
     
    136135
    137136
    138 static void init(pthread_mutex_t* plock){
     137static void init(pthread_mutex_t * plock) {
    139138        static_assert(sizeof(pthread_mutex_t) >= sizeof(simple_owner_lock),"sizeof(pthread_mutex_t) < sizeof(simple_owner_lock)");
    140         simple_owner_lock* _lock = (simple_owner_lock*)plock;
     139        simple_owner_lock * _lock = (simple_owner_lock *)plock;
    141140        ?{}(*_lock);
    142141}
    143142
    144 static simple_owner_lock* get(pthread_mutex_t* plock){
     143static simple_owner_lock * get(pthread_mutex_t * plock) {
    145144        static_assert(sizeof(pthread_mutex_t) >= sizeof(simple_owner_lock),"sizeof(pthread_mutex_t) < sizeof(simple_owner_lock)");
    146         return (simple_owner_lock*)plock;
    147 }
    148 
    149 static void destroy(pthread_mutex_t* plock){
     145        return (simple_owner_lock *)plock;
     146}
     147
     148static void destroy(pthread_mutex_t * plock) {
    150149        static_assert(sizeof(pthread_mutex_t) >= sizeof(simple_owner_lock),"sizeof(pthread_mutex_t) < sizeof(simple_owner_lock)");
    151150        ^?{}(*get(plock));
     
    157156                int detachstate;
    158157                size_t stacksize;
    159                 void *stackaddr;
     158                void * stackaddr;
    160159                int policy;
    161160                int inheritsched;
     
    163162} typedef cfaPthread_attr_t;
    164163
    165 static const cfaPthread_attr_t default_attrs{
     164static const cfaPthread_attr_t default_attrs {
    166165        0,
    167166        0,
    168         (size_t)65000,
    169         (void *)NULL,
     167        65_000,
     168        NULL,
    170169        0,
    171170        0,
     
    173172};
    174173
    175 static cfaPthread_attr_t* get(const pthread_attr_t* attr){
    176         static_assert(sizeof(pthread_attr_t) >= sizeof(cfaPthread_attr_t),"sizeof(pthread_attr_t) < sizeof(cfaPthread_attr_t)");
    177         return (cfaPthread_attr_t*)attr;
     174static cfaPthread_attr_t * get(const pthread_attr_t * attr) {
     175        static_assert(sizeof(pthread_attr_t) >= sizeof(cfaPthread_attr_t), "sizeof(pthread_attr_t) < sizeof(cfaPthread_attr_t)");
     176        return (cfaPthread_attr_t *)attr;
    178177}
    179178
     
    190189
    191190        // pthreads return value
    192         void *joinval;
     191        void * joinval;
    193192
    194193        // pthread attributes
    195194        pthread_attr_t pthread_attr;
    196195
    197         void *(*start_routine)(void *);
    198         void *start_arg;
     196        void *(* start_routine)(void *);
     197        void * start_arg;
    199198
    200199        // thread local data
    201         pthread_values* pthreadData;
     200        pthread_values * pthreadData;
    202201
    203202        // flag used for tryjoin
     
    207206/* thread part routines */
    208207//  cfaPthread entry point
    209 void main(cfaPthread& _thread) with(_thread){
    210         joinval =  start_routine(start_arg);
     208void main(cfaPthread & _thread) with(_thread) {
     209        joinval = start_routine(start_arg);
    211210        isTerminated = true;
    212211}
    213212
    214 static cfaPthread *lookup( pthread_t p ){
    215         static_assert(sizeof(pthread_t) >= sizeof(cfaPthread*),"sizeof(pthread_t) < sizeof(cfaPthread*)");
    216         return (cfaPthread*)p;
    217 }
    218 
    219 static void pthread_deletespecific_( pthread_values* values )  { // see uMachContext::invokeTask
    220         pthread_values* value;
    221         pthread_keys* key;
     213static cfaPthread * lookup( pthread_t p ) {
     214        static_assert(sizeof(pthread_t) >= sizeof(cfaPthread *),"sizeof(pthread_t) < sizeof(cfaPthread *)");
     215        return (cfaPthread *)p;
     216}
     217
     218static void pthread_deletespecific_( pthread_values * values )  { // see uMachContext::invokeTask
     219        pthread_values * value;
     220        pthread_keys * key;
    222221        bool destcalled = true;
    223         if (values != NULL){
     222        if (values != NULL) {
    224223                for ( int attempts = 0; attempts < PTHREAD_DESTRUCTOR_ITERATIONS && destcalled ; attempts += 1 ) {
    225224                        destcalled = false;
    226225                        lock(key_lock);
    227                         for (int i = 0; i < PTHREAD_KEYS_MAX; i++){
     226                        for ( int i = 0; i < PTHREAD_KEYS_MAX; i++ ) {
    228227                                // for each valid key
    229                                 if ( values[i].in_use){
     228                                if ( values[i].in_use) {
    230229                                        value = &values[i];
    231230                                        key = &cfa_pthread_keys[i];
     
    234233                                        // if  a  key  value  has  a  non-NULL  destructor pointer,  and  the  thread  has  a  non-NULL  value associated with that key,
    235234                                        // the value of the key is set to NULL, and then the function pointed to is called with the previously associated value as its sole argument.
    236                                         if (value->value != NULL && key->destructor != NULL){
     235                                        if (value->value != NULL && key->destructor != NULL) {
    237236                                                unlock(key_lock);
    238237                                                key->destructor(value->value); // run destructor
     
    249248}
    250249
    251 static void ^?{}(cfaPthread & mutex t){
     250static void ^?{}(cfaPthread & mutex t) {
    252251        // delete pthread local storage
    253252        pthread_values * values = t.pthreadData;
     
    255254}
    256255
    257 static void ?{}(cfaPthread &t, pthread_t* _thread, const pthread_attr_t * _attr,void *(*start_routine)(void *), void * arg) {
    258         static_assert(sizeof(pthread_t) >= sizeof(cfaPthread*), "pthread_t too small to hold a pointer: sizeof(pthread_t) < sizeof(cfaPthread*)");
     256static void ?{}(cfaPthread & t, pthread_t * _thread, const pthread_attr_t * _attr,void *(* start_routine)(void *), void * arg) {
     257        static_assert(sizeof(pthread_t) >= sizeof(cfaPthread *), "pthread_t too small to hold a pointer: sizeof(pthread_t) < sizeof(cfaPthread *)");
    259258
    260259        // set up user thread stackSize
     
    278277        //######################### Pthread Attrs #########################
    279278
    280         int pthread_attr_init(pthread_attr_t *attr) libcfa_public __THROW {
    281                 cfaPthread_attr_t* _attr = get(attr);
     279        int pthread_attr_init(pthread_attr_t * attr) libcfa_public __THROW {
     280                cfaPthread_attr_t * _attr = get(attr);
    282281                ?{}(*_attr, default_attrs);
    283282                return 0;
    284283        }
    285         int pthread_attr_destroy(pthread_attr_t *attr) libcfa_public __THROW {
     284        int pthread_attr_destroy(pthread_attr_t * attr) libcfa_public __THROW {
    286285                ^?{}(*get(attr));
    287286                return 0;
    288287        }
    289288
    290         int pthread_attr_setscope( pthread_attr_t *attr, int contentionscope ) libcfa_public __THROW {
     289        int pthread_attr_setscope( pthread_attr_t * attr, int contentionscope ) libcfa_public __THROW {
    291290                get( attr )->contentionscope = contentionscope;
    292291                return 0;
    293292        } // pthread_attr_setscope
    294293
    295         int pthread_attr_getscope( const pthread_attr_t *attr, int *contentionscope ) libcfa_public __THROW {
     294        int pthread_attr_getscope( const pthread_attr_t * attr, int * contentionscope ) libcfa_public __THROW {
    296295                *contentionscope = get( attr )->contentionscope;
    297296                return 0;
    298297        } // pthread_attr_getscope
    299298
    300         int pthread_attr_setdetachstate( pthread_attr_t *attr, int detachstate ) libcfa_public __THROW {
     299        int pthread_attr_setdetachstate( pthread_attr_t * attr, int detachstate ) libcfa_public __THROW {
    301300                get( attr )->detachstate = detachstate;
    302301                return 0;
    303302        } // pthread_attr_setdetachstate
    304303
    305         int pthread_attr_getdetachstate( const pthread_attr_t *attr, int *detachstate ) libcfa_public __THROW {
     304        int pthread_attr_getdetachstate( const pthread_attr_t * attr, int * detachstate ) libcfa_public __THROW {
    306305                *detachstate = get( attr )->detachstate;
    307306                return 0;
    308307        } // pthread_attr_getdetachstate
    309308
    310         int pthread_attr_setstacksize( pthread_attr_t *attr, size_t stacksize ) libcfa_public __THROW {
     309        int pthread_attr_setstacksize( pthread_attr_t * attr, size_t stacksize ) libcfa_public __THROW {
    311310                get( attr )->stacksize = stacksize;
    312311                return 0;
    313312        } // pthread_attr_setstacksize
    314313
    315         int pthread_attr_getstacksize( const pthread_attr_t *attr, size_t *stacksize ) libcfa_public __THROW {
     314        int pthread_attr_getstacksize( const pthread_attr_t * attr, size_t * stacksize ) libcfa_public __THROW {
    316315                *stacksize = get( attr )->stacksize;
    317316                return 0;
     
    326325        } // pthread_attr_setguardsize
    327326
    328         int pthread_attr_setstackaddr( pthread_attr_t *attr, void *stackaddr ) libcfa_public __THROW {
     327        int pthread_attr_setstackaddr( pthread_attr_t * attr, void * stackaddr ) libcfa_public __THROW {
    329328                get( attr )->stackaddr = stackaddr;
    330329                return 0;
    331330        } // pthread_attr_setstackaddr
    332331
    333         int pthread_attr_getstackaddr( const pthread_attr_t *attr, void **stackaddr ) libcfa_public __THROW {
     332        int pthread_attr_getstackaddr( const pthread_attr_t * attr, void ** stackaddr ) libcfa_public __THROW {
    334333                *stackaddr = get( attr )->stackaddr;
    335334                return 0;
    336335        } // pthread_attr_getstackaddr
    337336
    338         int pthread_attr_setstack( pthread_attr_t *attr, void *stackaddr, size_t stacksize ) libcfa_public __THROW {
     337        int pthread_attr_setstack( pthread_attr_t * attr, void * stackaddr, size_t stacksize ) libcfa_public __THROW {
    339338                get( attr )->stackaddr = stackaddr;
    340339                get( attr )->stacksize = stacksize;
     
    342341        } // pthread_attr_setstack
    343342
    344         int pthread_attr_getstack( const pthread_attr_t *attr, void **stackaddr, size_t *stacksize ) libcfa_public __THROW {
     343        int pthread_attr_getstack( const pthread_attr_t * attr, void ** stackaddr, size_t * stacksize ) libcfa_public __THROW {
    345344                *stackaddr = get( attr )->stackaddr;
    346345                *stacksize = get( attr )->stacksize;
     
    351350        // already running thread threadID. It shall be called on unitialized attr
    352351        // and destroyed with pthread_attr_destroy when no longer needed.
    353         int pthread_getattr_np( pthread_t threadID, pthread_attr_t *attr ) libcfa_public __THROW { // GNU extension
     352        int pthread_getattr_np( pthread_t threadID, pthread_attr_t * attr ) libcfa_public __THROW { // GNU extension
    354353                check_nonnull(attr);
    355354
     
    363362        //######################### Threads #########################
    364363
    365         int pthread_create(pthread_t * _thread, const pthread_attr_t * attr, void *(*start_routine)(void *), void * arg) libcfa_public __THROW {
    366                 cfaPthread *t = alloc();
     364        int pthread_create(pthread_t * _thread, const pthread_attr_t * attr, void *(* start_routine)(void *), void * arg) libcfa_public __THROW {
     365                cfaPthread * t = alloc();
    367366                (*t){_thread, attr, start_routine, arg};
    368367                return 0;
    369368        }
    370369
    371 
    372         int pthread_join(pthread_t _thread, void **value_ptr) libcfa_public __THROW {
     370        int pthread_join(pthread_t _thread, void ** value_ptr) libcfa_public __THROW {
    373371                // if thread is invalid
    374372                if (_thread == NULL) return EINVAL;
     
    376374
    377375                // get user thr pointer
    378                 cfaPthread* p = lookup(_thread);
     376                cfaPthread * p = lookup(_thread);
    379377                try {
    380378                        join(*p);
     
    389387        }
    390388
    391         int pthread_tryjoin_np(pthread_t _thread, void **value_ptr) libcfa_public __THROW {
     389        int pthread_tryjoin_np(pthread_t _thread, void ** value_ptr) libcfa_public __THROW {
    392390                // if thread is invalid
    393391                if (_thread == NULL) return EINVAL;
    394392                if (_thread == pthread_self()) return EDEADLK;
    395393
    396                 cfaPthread* p = lookup(_thread);
     394                cfaPthread * p = lookup(_thread);
    397395
    398396                // thread not finished ?
     
    412410        void pthread_exit(void * status) libcfa_public __THROW {
    413411                pthread_t pid = pthread_self();
    414                 cfaPthread* _thread = (cfaPthread*)pid;
     412                cfaPthread * _thread = (cfaPthread *)pid;
    415413                _thread->joinval = status;  // set return value
    416414                _thread->isTerminated = 1;  // set terminated flag
     
    426424        //######################### Mutex #########################
    427425
    428         int pthread_mutex_init(pthread_mutex_t *_mutex, const pthread_mutexattr_t *attr) libcfa_public __THROW {
     426        int pthread_mutex_init(pthread_mutex_t *_mutex, const pthread_mutexattr_t * attr) libcfa_public __THROW {
    429427                check_nonnull(_mutex);
    430428                init(_mutex);
     
    435433        int pthread_mutex_destroy(pthread_mutex_t *_mutex) libcfa_public __THROW {
    436434                check_nonnull(_mutex);
    437                 simple_owner_lock* _lock = get(_mutex);
    438                 if (_lock->owner != NULL){
     435                simple_owner_lock * _lock = get(_mutex);
     436                if (_lock->owner != NULL) {
    439437                        return EBUSY;
    440438                }
     
    446444                check_nonnull(_mutex);
    447445                mutex_check(_mutex);
    448                 simple_owner_lock* _lock = get(_mutex);
     446                simple_owner_lock * _lock = get(_mutex);
    449447                lock(*_lock);
    450448                return 0;
     
    453451        int pthread_mutex_unlock(pthread_mutex_t *_mutex) libcfa_public __THROW {
    454452                check_nonnull(_mutex);
    455                 simple_owner_lock* _lock = get(_mutex);
    456                 if (_lock->owner != active_thread()){
     453                simple_owner_lock * _lock = get(_mutex);
     454                if (_lock->owner != active_thread()) {
    457455                        return EPERM;
    458456                } // current thread does not hold the mutex
     
    463461        int pthread_mutex_trylock(pthread_mutex_t *_mutex) libcfa_public __THROW {
    464462                check_nonnull(_mutex);
    465                 simple_owner_lock* _lock = get(_mutex);
    466                 if (_lock->owner != active_thread() && _lock->owner != NULL){
     463                simple_owner_lock * _lock = get(_mutex);
     464                if (_lock->owner != active_thread() && _lock->owner != NULL) {
    467465                        return EBUSY;
    468466                }   // if mutex is owned
     
    474472
    475473        /* conditional variable routines */
    476         int pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *attr) libcfa_public __THROW {
     474        int pthread_cond_init(pthread_cond_t * cond, const pthread_condattr_t * attr) libcfa_public __THROW {
    477475                check_nonnull(cond);
    478476                init(cond);
     
    480478        }  //pthread_cond_init
    481479
    482         int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *_mutex) libcfa_public __THROW {
     480        int pthread_cond_wait(pthread_cond_t * cond, pthread_mutex_t *_mutex) libcfa_public __THROW {
    483481                check_nonnull(_mutex);
    484482                check_nonnull(cond);
     
    494492        } // pthread_cond_timedwait
    495493
    496         int pthread_cond_signal(pthread_cond_t *cond) libcfa_public __THROW {
     494        int pthread_cond_signal(pthread_cond_t * cond) libcfa_public __THROW {
    497495                check_nonnull(cond);
    498496                return notify_one(*get(cond));
    499497        } // pthread_cond_signal
    500498
    501         int pthread_cond_broadcast(pthread_cond_t *cond) libcfa_public __THROW {
     499        int pthread_cond_broadcast(pthread_cond_t * cond) libcfa_public __THROW {
    502500                check_nonnull(cond);
    503501                return notify_all(*get(cond));
    504502        } // pthread_cond_broadcast
    505503
    506         int pthread_cond_destroy(pthread_cond_t *cond) libcfa_public __THROW {
     504        int pthread_cond_destroy(pthread_cond_t * cond) libcfa_public __THROW {
    507505                check_nonnull(cond);
    508506                destroy(cond);
     
    514512        //######################### Local storage #########################
    515513
    516         int pthread_once(pthread_once_t *once_control, void (*init_routine)(void)) libcfa_public __THROW {
     514        int pthread_once(pthread_once_t * once_control, void (* init_routine)(void)) libcfa_public __THROW {
    517515                static_assert(sizeof(pthread_once_t) >= sizeof(int),"sizeof(pthread_once_t) < sizeof(int)");
    518516                check_nonnull(once_control);
     
    527525        } // pthread_once
    528526
    529         int pthread_key_create( pthread_key_t *key, void (*destructor)( void * ) ) libcfa_public __THROW {
     527        int pthread_key_create( pthread_key_t * key, void (* destructor)( void * ) ) libcfa_public __THROW {
    530528                lock(key_lock);
    531529                for ( int i = 0; i < PTHREAD_KEYS_MAX; i += 1 ) {
     
    562560        }   // pthread_key_delete
    563561
    564         int pthread_setspecific( pthread_key_t key, const void *value ) libcfa_public __THROW {
     562        int pthread_setspecific( pthread_key_t key, const void * value ) libcfa_public __THROW {
    565563                // get current thread
    566                 cfaPthread* t = lookup(pthread_self());
     564                cfaPthread * t = lookup(pthread_self());
    567565                // if current thread's pthreadData is NULL; initialize it
    568                 pthread_values* values;
    569                 if (t->pthreadData == NULL){
     566                pthread_values * values;
     567                if (t->pthreadData == NULL) {
    570568                        values = anew( PTHREAD_KEYS_MAX);
    571569                        t->pthreadData = values;
    572                         for (int i = 0;i < PTHREAD_KEYS_MAX; i++){
     570                        for ( int i = 0;i < PTHREAD_KEYS_MAX; i++ ) {
    573571                                t->pthreadData[i].in_use = false;
    574572                        }   // for
     
    593591        } //pthread_setspecific
    594592
    595         void* pthread_getspecific(pthread_key_t key) libcfa_public __THROW {
     593        void * pthread_getspecific(pthread_key_t key) libcfa_public __THROW {
    596594                if (key >= PTHREAD_KEYS_MAX || ! cfa_pthread_keys[key].in_use) return NULL;
    597595
    598596                // get current thread
    599                 cfaPthread* t = lookup(pthread_self());
     597                cfaPthread * t = lookup(pthread_self());
    600598                if (t->pthreadData == NULL) return NULL;
    601599                lock(key_lock);
     
    605603                        return NULL;
    606604                } // if
    607                 void *value = entry.value;
     605                void * value = entry.value;
    608606                unlock(key_lock);
    609607
     
    875873        //######################### Parallelism #########################
    876874
    877         int pthread_setaffinity_np( pthread_t /* __th */, size_t /* __cpusetsize */, __const cpu_set_t * /* __cpuset */ ) libcfa_public __THROW {
    878                 abort( "pthread_setaffinity_np" );
    879         } // pthread_setaffinity_np
    880 
    881         int pthread_getaffinity_np( pthread_t /* __th */, size_t /* __cpusetsize */, cpu_set_t * /* __cpuset */ ) libcfa_public __THROW {
    882                 abort( "pthread_getaffinity_np" );
    883         } // pthread_getaffinity_np
    884 
    885         int pthread_attr_setaffinity_np( pthread_attr_t * /* __attr */, size_t /* __cpusetsize */, __const cpu_set_t * /* __cpuset */ ) libcfa_public __THROW {
    886                 abort( "pthread_attr_setaffinity_np" );
    887         } // pthread_attr_setaffinity_np
    888 
    889         int pthread_attr_getaffinity_np( __const pthread_attr_t * /* __attr */, size_t /* __cpusetsize */, cpu_set_t * /* __cpuset */ ) libcfa_public __THROW {
    890                 abort( "pthread_attr_getaffinity_np" );
    891         } // pthread_attr_getaffinity_np
     875        // int pthread_setaffinity_np( pthread_t /* __th */, size_t /* __cpusetsize */, __const cpu_set_t * /* __cpuset */ ) libcfa_public __THROW {
     876        //      abort( "pthread_setaffinity_np" );
     877        // } // pthread_setaffinity_np
     878
     879        // int pthread_getaffinity_np( pthread_t /* __th */, size_t /* __cpusetsize */, cpu_set_t * /* __cpuset */ ) libcfa_public __THROW {
     880        //      abort( "pthread_getaffinity_np" );
     881        // } // pthread_getaffinity_np
     882
     883        // int pthread_attr_setaffinity_np( pthread_attr_t * /* __attr */, size_t /* __cpusetsize */, __const cpu_set_t * /* __cpuset */ ) libcfa_public __THROW {
     884        //      abort( "pthread_attr_setaffinity_np" );
     885        // } // pthread_attr_setaffinity_np
     886
     887        // int pthread_attr_getaffinity_np( __const pthread_attr_t * /* __attr */, size_t /* __cpusetsize */, cpu_set_t * /* __cpuset */ ) libcfa_public __THROW {
     888        //      abort( "pthread_attr_getaffinity_np" );
     889        // } // pthread_attr_getaffinity_np
    892890
    893891        //######################### Cancellation #########################
     
    906904        } // pthread_cancel
    907905
    908         int pthread_setcancelstate( int state, int *oldstate ) libcfa_public __THROW {
     906        int pthread_setcancelstate( int state, int * oldstate ) libcfa_public __THROW {
    909907                abort("pthread_setcancelstate not implemented");
    910908                return 0;
    911909        } // pthread_setcancelstate
    912910
    913         int pthread_setcanceltype( int type, int *oldtype ) libcfa_public __THROW {
     911        int pthread_setcanceltype( int type, int * oldtype ) libcfa_public __THROW {
    914912                abort("pthread_setcanceltype not implemented");
    915913                return 0;
     
    918916
    919917#pragma GCC diagnostic pop
    920 
  • libcfa/src/concurrency/ready_queue.cfa

    r1180175 r640b3df  
    1515
    1616#define __cforall_thread__
    17 #define _GNU_SOURCE
    1817
    1918// #define __CFA_DEBUG_PRINT_READY_QUEUE__
  • libcfa/src/concurrency/thread.cfa

    r1180175 r640b3df  
    1010// Created On       : Tue Jan 17 12:27:26 2017
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sun Dec 11 20:56:54 2022
    13 // Update Count     : 102
     12// Last Modified On : Mon Jan  9 08:42:33 2023
     13// Update Count     : 103
    1414//
    1515
    1616#define __cforall_thread__
    17 #define _GNU_SOURCE
    1817
    1918#include "thread.hfa"
  • libcfa/src/interpose.cfa

    r1180175 r640b3df  
    1010// Created On       : Wed Mar 29 16:10:31 2017
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Jan  5 22:23:57 2023
    13 // Update Count     : 180
     12// Last Modified On : Sun Feb 19 17:09:16 2023
     13// Update Count     : 183
    1414//
    1515
     
    4545        union { generic_fptr_t fptr; void * ptr; } originalFunc;
    4646
    47         #if defined( _GNU_SOURCE )
    48                 if ( version ) {
    49                         originalFunc.ptr = dlvsym( library, symbol, version );
    50                 } else {
    51                         originalFunc.ptr = dlsym( library, symbol );
    52                 }
    53         #else
    54                 originalFunc.ptr = dlsym( library, symbol );
    55         #endif // _GNU_SOURCE
    56 
     47        originalFunc.ptr = dlsym( library, symbol );
    5748        error = dlerror();
    5849        if ( error ) abort( "interpose_symbol : internal error, %s\n", error );
     
    6253
    6354static generic_fptr_t interpose_symbol( const char symbol[], const char version[] ) {
    64         const char * error;
    65 
    6655        static void * library;
    6756        static void * pthread_library;
     57
    6858        if ( ! library ) {
    69                 #if defined( RTLD_NEXT )
    70                         library = RTLD_NEXT;
    71                 #else
    72                         // missing RTLD_NEXT => must hard-code library name, assuming libstdc++
    73                         library = dlopen( "libc.so.6", RTLD_LAZY );
    74                         error = dlerror();
    75                         if ( error ) {
    76                                 abort( "interpose_symbol : failed to open libc, %s\n", error );
    77                         }
    78                 #endif
     59                library = dlopen( "libc.so.6", RTLD_LAZY );
     60                const char * error = dlerror();
     61                if ( error ) {
     62                        abort( "interpose_symbol : failed to open libc, %s\n", error );
     63                } // if
    7964        } // if
    8065        if ( ! pthread_library ) {
    81                 #if defined( RTLD_NEXT )
    82                         pthread_library = RTLD_NEXT;
    83                 #else
    84                         // missing RTLD_NEXT => must hard-code library name, assuming libstdc++
    85                         pthread_library = dlopen( "libpthread.so", RTLD_LAZY );
    86                         error = dlerror();
    87                         if ( error ) {
    88                                 abort( "interpose_symbol : failed to open libpthread, %s\n", error );
    89                         }
    90                 #endif
     66                pthread_library = dlopen( "libpthread.so", RTLD_LAZY );
     67                const char * error = dlerror();
     68                if ( error ) {
     69                        abort( "interpose_symbol : failed to open libpthread, %s\n", error );
     70                } // if
    9171        } // if
    9272
  • libcfa/src/interpose_thread.cfa

    r1180175 r640b3df  
    3939        const char version[]
    4040) libcfa_public {
    41         const char * error;
    42 
    4341        static void * library;
    4442        if ( ! library ) {
    45                 #if defined( RTLD_NEXT )
    46                         library = RTLD_NEXT;
    47                 #else
    48                         // missing RTLD_NEXT => must hard-code library name, assuming libstdc++
    49                         library = dlopen( "libpthread.so", RTLD_LAZY );
    50                         error = dlerror();
    51                         if ( error ) {
    52                                 abort( "interpose_symbol : failed to open libpthread, %s\n", error );
    53                         }
    54                 #endif
     43                library = dlopen( "libpthread.so", RTLD_LAZY );
     44                const char * error = dlerror();
     45                if ( error ) {
     46                        abort( "interpose_symbol : failed to open libpthread, %s\n", error );
     47                }
    5548        } // if
    5649
  • libcfa/src/iostream.cfa

    r1180175 r640b3df  
    1010// Created On       : Wed May 27 17:56:53 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sat Aug 27 15:04:15 2022
    13 // Update Count     : 1358
     12// Last Modified On : Mon Jan  9 09:27:58 2023
     13// Update Count     : 1361
    1414//
    1515
     
    667667                        } /* if */ \
    668668                        if ( ! f.flags.nobsdp || (exp10 < SUFFIXES_START) || (exp10 > SUFFIXES_END) ) { \
    669                                 len2 = snprintf( &buf[len], size - len, "e%d", exp10 ); \
     669                                len2 = snprintf( &buf[len], size - len, "e%d", (int)exp10 /* ambiguity with function exp10 */ ); \
    670670                        } else { \
    671671                                len2 = snprintf( &buf[len], size - len, "%s", suffixes[(exp10 - SUFFIXES_START) / 3] ); \
  • libcfa/src/limits.cfa

    r1180175 r640b3df  
    1010// Created On       : Wed Apr  6 18:06:52 2016
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Jan  5 22:27:40 2023
    13 // Update Count     : 84
     12// Last Modified On : Sun Jan  8 18:53:17 2023
     13// Update Count     : 86
    1414//
    1515
    16 #define _GNU_SOURCE                                                                             // access long double M_*l in math.h
     16// need _GNU_SOURCE to access long double M_*l in math.h
    1717#include <limits.h>
    1818#include <float.h>
  • libcfa/src/stdlib.cfa

    r1180175 r640b3df  
    1010// Created On       : Thu Jan 28 17:10:29 2016
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Fri Dec  9 15:11:30 2022
    13 // Update Count     : 631
     12// Last Modified On : Thu Feb 16 16:31:34 2023
     13// Update Count     : 633
    1414//
    1515
     
    2020//---------------------------------------
    2121
    22 #define _XOPEN_SOURCE 600                                                               // posix_memalign, *rand48
    2322#include <string.h>                                                                             // memcpy, memset
    2423//#include <math.h>                                                                             // fabsf, fabs, fabsl
  • src/AST/Create.cpp

    r1180175 r640b3df  
    2020#include "AST/Decl.hpp"
    2121#include "AST/Type.hpp"
     22#include "Common/Iterate.hpp"
    2223
    2324namespace ast {
  • src/AST/Decl.cpp

    r1180175 r640b3df  
    2020#include <unordered_map>
    2121
    22 #include "Common/utility.h"
     22#include "Common/Eval.h"       // for eval
    2323
    2424#include "Fwd.hpp"             // for UniqueId
  • src/AST/Pass.impl.hpp

    r1180175 r640b3df  
    2222#include "AST/TranslationUnit.hpp"
    2323#include "AST/TypeSubstitution.hpp"
     24#include "Common/Iterate.hpp"
    2425
    2526#define VISIT_START( node ) \
  • src/AST/Pass.proto.hpp

    r1180175 r640b3df  
    1818
    1919#include "Common/Stats/Heap.h"
    20 
    2120namespace ast {
    22 template<typename core_t>
    23 class Pass;
    24 
    25 class TranslationUnit;
    26 
    27 struct PureVisitor;
    28 
    29 template<typename node_t>
    30 node_t * deepCopy( const node_t * localRoot );
    31 
    32 namespace __pass {
    33         typedef std::function<void( void * )> cleanup_func_t;
    34         typedef std::function<void( cleanup_func_t, void * )> at_cleanup_t;
    35 
    36 
    37         // boolean reference that may be null
    38         // either refers to a boolean value or is null and returns true
    39         class bool_ref {
    40         public:
    41                 bool_ref() = default;
    42                 ~bool_ref() = default;
    43 
    44                 operator bool() { return m_ref ? *m_ref : true; }
    45                 bool operator=( bool val ) { assert(m_ref); return *m_ref = val; }
    46 
    47         private:
    48 
    49                 friend class visit_children_guard;
    50 
    51                 bool * set( bool * val ) {
    52                         bool * prev = m_ref;
    53                         m_ref = val;
    54                         return prev;
    55                 }
    56 
    57                 bool * m_ref = nullptr;
     21        template<typename core_t> class Pass;
     22        class TranslationUnit;
     23        struct PureVisitor;
     24        template<typename node_t> node_t * deepCopy( const node_t * );
     25}
     26
     27namespace ast::__pass {
     28
     29typedef std::function<void( void * )> cleanup_func_t;
     30typedef std::function<void( cleanup_func_t, void * )> at_cleanup_t;
     31
     32// boolean reference that may be null
     33// either refers to a boolean value or is null and returns true
     34class bool_ref {
     35public:
     36        bool_ref() = default;
     37        ~bool_ref() = default;
     38
     39        operator bool() { return m_ref ? *m_ref : true; }
     40        bool operator=( bool val ) { assert(m_ref); return *m_ref = val; }
     41
     42private:
     43
     44        friend class visit_children_guard;
     45
     46        bool * set( bool * val ) {
     47                bool * prev = m_ref;
     48                m_ref = val;
     49                return prev;
     50        }
     51
     52        bool * m_ref = nullptr;
     53};
     54
     55// Implementation of the guard value
     56// Created inside the visit scope
     57class guard_value {
     58public:
     59        /// Push onto the cleanup
     60        guard_value( at_cleanup_t * at_cleanup ) {
     61                if( at_cleanup ) {
     62                        *at_cleanup = [this]( cleanup_func_t && func, void* val ) {
     63                                push( std::move( func ), val );
     64                        };
     65                }
     66        }
     67
     68        ~guard_value() {
     69                while( !cleanups.empty() ) {
     70                        auto& cleanup = cleanups.top();
     71                        cleanup.func( cleanup.val );
     72                        cleanups.pop();
     73                }
     74        }
     75
     76        void push( cleanup_func_t && func, void* val ) {
     77                cleanups.emplace( std::move(func), val );
     78        }
     79
     80private:
     81        struct cleanup_t {
     82                cleanup_func_t func;
     83                void * val;
     84
     85                cleanup_t( cleanup_func_t&& func, void * val ) : func(func), val(val) {}
    5886        };
    5987
    60         // Implementation of the guard value
    61         // Created inside the visit scope
    62         class guard_value {
    63         public:
    64                 /// Push onto the cleanup
    65                 guard_value( at_cleanup_t * at_cleanup ) {
    66                         if( at_cleanup ) {
    67                                 *at_cleanup = [this]( cleanup_func_t && func, void* val ) {
    68                                         push( std::move( func ), val );
    69                                 };
    70                         }
    71                 }
    72 
    73                 ~guard_value() {
    74                         while( !cleanups.empty() ) {
    75                                 auto& cleanup = cleanups.top();
    76                                 cleanup.func( cleanup.val );
    77                                 cleanups.pop();
    78                         }
    79                 }
    80 
    81                 void push( cleanup_func_t && func, void* val ) {
    82                         cleanups.emplace( std::move(func), val );
    83                 }
    84 
    85         private:
    86                 struct cleanup_t {
    87                         cleanup_func_t func;
    88                         void * val;
    89 
    90                         cleanup_t( cleanup_func_t&& func, void * val ) : func(func), val(val) {}
    91                 };
    92 
    93                 std::stack< cleanup_t, std::vector<cleanup_t> > cleanups;
     88        std::stack< cleanup_t, std::vector<cleanup_t> > cleanups;
     89};
     90
     91// Guard structure implementation for whether or not children should be visited
     92class visit_children_guard {
     93public:
     94
     95        visit_children_guard( bool_ref * ref )
     96                : m_val ( true )
     97                , m_prev( ref ? ref->set( &m_val ) : nullptr )
     98                , m_ref ( ref )
     99        {}
     100
     101        ~visit_children_guard() {
     102                if( m_ref ) {
     103                        m_ref->set( m_prev );
     104                }
     105        }
     106
     107        operator bool() { return m_val; }
     108
     109private:
     110        bool       m_val;
     111        bool     * m_prev;
     112        bool_ref * m_ref;
     113};
     114
     115/// "Short hand" to check if this is a valid previsit function
     116/// Mostly used to make the static_assert look (and print) prettier
     117template<typename core_t, typename node_t>
     118struct is_valid_previsit {
     119        using ret_t = decltype( std::declval<core_t*>()->previsit( std::declval<const node_t *>() ) );
     120
     121        static constexpr bool value = std::is_void< ret_t >::value ||
     122                std::is_base_of<const node_t, typename std::remove_pointer<ret_t>::type >::value;
     123};
     124
     125/// The result is a single node.
     126template< typename node_t >
     127struct result1 {
     128        bool differs = false;
     129        const node_t * value = nullptr;
     130
     131        template< typename object_t, typename super_t, typename field_t >
     132        void apply( object_t *, field_t super_t::* field );
     133};
     134
     135/// The result is a container of statements.
     136template< template<class...> class container_t >
     137struct resultNstmt {
     138        /// The delta/change on a single node.
     139        struct delta {
     140                ptr<Stmt> new_val;
     141                ssize_t old_idx;
     142                bool is_old;
     143
     144                delta(const Stmt * s, ssize_t i, bool old) :
     145                        new_val(s), old_idx(i), is_old(old) {}
    94146        };
    95147
    96         // Guard structure implementation for whether or not children should be visited
    97         class visit_children_guard {
    98         public:
    99 
    100                 visit_children_guard( bool_ref * ref )
    101                         : m_val ( true )
    102                         , m_prev( ref ? ref->set( &m_val ) : nullptr )
    103                         , m_ref ( ref )
    104                 {}
    105 
    106                 ~visit_children_guard() {
    107                         if( m_ref ) {
    108                                 m_ref->set( m_prev );
    109                         }
    110                 }
    111 
    112                 operator bool() { return m_val; }
    113 
    114         private:
    115                 bool       m_val;
    116                 bool     * m_prev;
    117                 bool_ref * m_ref;
    118         };
    119 
    120         /// "Short hand" to check if this is a valid previsit function
    121         /// Mostly used to make the static_assert look (and print) prettier
     148        bool differs = false;
     149        container_t< delta > values;
     150
     151        template< typename object_t, typename super_t, typename field_t >
     152        void apply( object_t *, field_t super_t::* field );
     153
     154        template< template<class...> class incontainer_t >
     155        void take_all( incontainer_t<ptr<Stmt>> * stmts );
     156
     157        template< template<class...> class incontainer_t >
     158        void take_all( incontainer_t<ptr<Decl>> * decls );
     159};
     160
     161/// The result is a container of nodes.
     162template< template<class...> class container_t, typename node_t >
     163struct resultN {
     164        bool differs = false;
     165        container_t<ptr<node_t>> values;
     166
     167        template< typename object_t, typename super_t, typename field_t >
     168        void apply( object_t *, field_t super_t::* field );
     169};
     170
     171/// Used by previsit implementation
     172/// We need to reassign the result to 'node', unless the function
     173/// returns void, then we just leave 'node' unchanged
     174template<bool is_void>
     175struct __assign;
     176
     177template<>
     178struct __assign<true> {
    122179        template<typename core_t, typename node_t>
    123         struct is_valid_previsit {
    124                 using ret_t = decltype( std::declval<core_t*>()->previsit( std::declval<const node_t *>() ) );
    125 
    126                 static constexpr bool value = std::is_void< ret_t >::value ||
    127                         std::is_base_of<const node_t, typename std::remove_pointer<ret_t>::type >::value;
    128         };
    129 
    130         /// The result is a single node.
    131         template< typename node_t >
    132         struct result1 {
    133                 bool differs = false;
    134                 const node_t * value = nullptr;
    135 
    136                 template< typename object_t, typename super_t, typename field_t >
    137                 void apply( object_t *, field_t super_t::* field );
    138         };
    139 
    140         /// The result is a container of statements.
    141         template< template<class...> class container_t >
    142         struct resultNstmt {
    143                 /// The delta/change on a single node.
    144                 struct delta {
    145                         ptr<Stmt> new_val;
    146                         ssize_t old_idx;
    147                         bool is_old;
    148 
    149                         delta(const Stmt * s, ssize_t i, bool old) :
    150                                 new_val(s), old_idx(i), is_old(old) {}
    151                 };
    152 
    153                 bool differs = false;
    154                 container_t< delta > values;
    155 
    156                 template< typename object_t, typename super_t, typename field_t >
    157                 void apply( object_t *, field_t super_t::* field );
    158 
    159                 template< template<class...> class incontainer_t >
    160                 void take_all( incontainer_t<ptr<Stmt>> * stmts );
    161 
    162                 template< template<class...> class incontainer_t >
    163                 void take_all( incontainer_t<ptr<Decl>> * decls );
    164         };
    165 
    166         /// The result is a container of nodes.
    167         template< template<class...> class container_t, typename node_t >
    168         struct resultN {
    169                 bool differs = false;
    170                 container_t<ptr<node_t>> values;
    171 
    172                 template< typename object_t, typename super_t, typename field_t >
    173                 void apply( object_t *, field_t super_t::* field );
    174         };
    175 
    176         /// Used by previsit implementation
    177         /// We need to reassign the result to 'node', unless the function
    178         /// returns void, then we just leave 'node' unchanged
    179         template<bool is_void>
    180         struct __assign;
    181 
    182         template<>
    183         struct __assign<true> {
    184                 template<typename core_t, typename node_t>
    185                 static inline void result( core_t & core, const node_t * & node ) {
    186                         core.previsit( node );
    187                 }
    188         };
    189 
    190         template<>
    191         struct __assign<false> {
    192                 template<typename core_t, typename node_t>
    193                 static inline void result( core_t & core, const node_t * & node ) {
    194                         node = core.previsit( node );
    195                         assertf(node, "Previsit must not return NULL");
    196                 }
    197         };
    198 
    199         /// Used by postvisit implementation
    200         /// We need to return the result unless the function
    201         /// returns void, then we just return the original node
    202         template<bool is_void>
    203         struct __return;
    204 
    205         template<>
    206         struct __return<true> {
    207                 template<typename core_t, typename node_t>
    208                 static inline const node_t * result( core_t & core, const node_t * & node ) {
    209                         core.postvisit( node );
    210                         return node;
    211                 }
    212         };
    213 
    214         template<>
    215         struct __return<false> {
    216                 template<typename core_t, typename node_t>
    217                 static inline auto result( core_t & core, const node_t * & node ) {
    218                         return core.postvisit( node );
    219                 }
    220         };
    221 
    222         //-------------------------------------------------------------------------------------------------------------------------------------------------------------------------
    223         // Deep magic (a.k.a template meta programming) to make the templated visitor work
    224         // Basically the goal is to make 2 previsit
    225         // 1 - Use when a pass implements a valid previsit. This uses overloading which means the any overload of
    226         //     'pass.previsit( node )' that compiles will be used for that node for that type
    227         //     This requires that this option only compile for passes that actually define an appropriate visit.
    228         //     SFINAE will make sure the compilation errors in this function don't halt the build.
    229         //     See http://en.cppreference.com/w/cpp/language/sfinae for details on SFINAE
    230         // 2 - Since the first implementation might not be specilizable, the second implementation exists and does nothing.
    231         //     This is needed only to eliminate the need for passes to specify any kind of handlers.
    232         //     The second implementation only works because it has a lower priority. This is due to the bogus last parameter.
    233         //     The second implementation takes a long while the first takes an int. Since the caller always passes an literal 0
    234         //     the first implementation takes priority in regards to overloading.
    235         //-------------------------------------------------------------------------------------------------------------------------------------------------------------------------
    236         // PreVisit : may mutate the pointer passed in if the node is mutated in the previsit call
     180        static inline void result( core_t & core, const node_t * & node ) {
     181                core.previsit( node );
     182        }
     183};
     184
     185template<>
     186struct __assign<false> {
    237187        template<typename core_t, typename node_t>
    238         static inline auto previsit( core_t & core, const node_t * & node, int ) -> decltype( core.previsit( node ), void() ) {
    239                 static_assert(
    240                         is_valid_previsit<core_t, node_t>::value,
    241                         "Previsit may not change the type of the node. It must return its paremeter or void."
    242                 );
    243 
    244                 __assign<
    245                         std::is_void<
    246                                 decltype( core.previsit( node ) )
    247                         >::value
    248                 >::result( core, node );
    249         }
    250 
     188        static inline void result( core_t & core, const node_t * & node ) {
     189                node = core.previsit( node );
     190                assertf(node, "Previsit must not return NULL");
     191        }
     192};
     193
     194/// Used by postvisit implementation
     195/// We need to return the result unless the function
     196/// returns void, then we just return the original node
     197template<bool is_void>
     198struct __return;
     199
     200template<>
     201struct __return<true> {
    251202        template<typename core_t, typename node_t>
    252         static inline auto previsit( core_t &, const node_t *, long ) {}
    253 
    254         // PostVisit : never mutates the passed pointer but may return a different node
     203        static inline const node_t * result( core_t & core, const node_t * & node ) {
     204                core.postvisit( node );
     205                return node;
     206        }
     207};
     208
     209template<>
     210struct __return<false> {
    255211        template<typename core_t, typename node_t>
    256         static inline auto postvisit( core_t & core, const node_t * node, int ) ->
    257                 decltype( core.postvisit( node ), node->accept( *(Visitor*)nullptr ) )
    258         {
    259                 return __return<
    260                         std::is_void<
    261                                 decltype( core.postvisit( node ) )
    262                         >::value
    263                 >::result( core, node );
    264         }
    265 
    266         template<typename core_t, typename node_t>
    267         static inline const node_t * postvisit( core_t &, const node_t * node, long ) { return node; }
    268 
    269         //-------------------------------------------------------------------------------------------------------------------------------------------------------------------------
    270         // Deep magic (a.k.a template meta programming) continued
    271         // To make the templated visitor be more expressive, we allow 'accessories' : classes/structs the implementation can inherit
    272         // from in order to get extra functionallity for example
    273         // class ErrorChecker : WithShortCircuiting { ... };
    274         // Pass<ErrorChecker> checker;
    275         // this would define a pass that uses the templated visitor with the additionnal feature that it has short circuiting
    276         // Note that in all cases the accessories are not required but guarantee the requirements of the feature is matched
    277         //-------------------------------------------------------------------------------------------------------------------------------------------------------------------------
    278         // For several accessories, the feature is enabled by detecting that a specific field is present
    279         // Use a macro the encapsulate the logic of detecting a particular field
    280         // The type is not strictly enforced but does match the accessory
    281         #define FIELD_PTR( name, default_type ) \
    282         template< typename core_t > \
    283         static inline auto name( core_t & core, int ) -> decltype( &core.name ) { return &core.name; } \
     212        static inline auto result( core_t & core, const node_t * & node ) {
     213                return core.postvisit( node );
     214        }
     215};
     216
     217//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------
     218// Deep magic (a.k.a template meta programming) to make the templated visitor work
     219// Basically the goal is to make 2 previsit
     220// 1 - Use when a pass implements a valid previsit. This uses overloading which means the any overload of
     221//     'pass.previsit( node )' that compiles will be used for that node for that type
     222//     This requires that this option only compile for passes that actually define an appropriate visit.
     223//     SFINAE will make sure the compilation errors in this function don't halt the build.
     224//     See http://en.cppreference.com/w/cpp/language/sfinae for details on SFINAE
     225// 2 - Since the first implementation might not be specilizable, the second implementation exists and does nothing.
     226//     This is needed only to eliminate the need for passes to specify any kind of handlers.
     227//     The second implementation only works because it has a lower priority. This is due to the bogus last parameter.
     228//     The second implementation takes a long while the first takes an int. Since the caller always passes an literal 0
     229//     the first implementation takes priority in regards to overloading.
     230//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------
     231// PreVisit : may mutate the pointer passed in if the node is mutated in the previsit call
     232template<typename core_t, typename node_t>
     233static inline auto previsit( core_t & core, const node_t * & node, int ) -> decltype( core.previsit( node ), void() ) {
     234        static_assert(
     235                is_valid_previsit<core_t, node_t>::value,
     236                "Previsit may not change the type of the node. It must return its paremeter or void."
     237        );
     238
     239        __assign<
     240                std::is_void<
     241                        decltype( core.previsit( node ) )
     242                >::value
     243        >::result( core, node );
     244}
     245
     246template<typename core_t, typename node_t>
     247static inline auto previsit( core_t &, const node_t *, long ) {}
     248
     249// PostVisit : never mutates the passed pointer but may return a different node
     250template<typename core_t, typename node_t>
     251static inline auto postvisit( core_t & core, const node_t * node, int ) ->
     252        decltype( core.postvisit( node ), node->accept( *(Visitor*)nullptr ) )
     253{
     254        return __return<
     255                std::is_void<
     256                        decltype( core.postvisit( node ) )
     257                >::value
     258        >::result( core, node );
     259}
     260
     261template<typename core_t, typename node_t>
     262static inline const node_t * postvisit( core_t &, const node_t * node, long ) { return node; }
     263
     264//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------
     265// Deep magic (a.k.a template meta programming) continued
     266// To make the templated visitor be more expressive, we allow 'accessories' : classes/structs the implementation can inherit
     267// from in order to get extra functionallity for example
     268// class ErrorChecker : WithShortCircuiting { ... };
     269// Pass<ErrorChecker> checker;
     270// this would define a pass that uses the templated visitor with the additionnal feature that it has short circuiting
     271// Note that in all cases the accessories are not required but guarantee the requirements of the feature is matched
     272//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------
     273// For several accessories, the feature is enabled by detecting that a specific field is present
     274// Use a macro the encapsulate the logic of detecting a particular field
     275// The type is not strictly enforced but does match the accessory
     276#define FIELD_PTR( name, default_type ) \
     277template< typename core_t > \
     278static inline auto name( core_t & core, int ) -> decltype( &core.name ) { return &core.name; } \
     279\
     280template< typename core_t > \
     281static inline default_type * name( core_t &, long ) { return nullptr; }
     282
     283// List of fields and their expected types
     284FIELD_PTR( typeSubs, const ast::TypeSubstitution * )
     285FIELD_PTR( stmtsToAddBefore, std::list< ast::ptr< ast::Stmt > > )
     286FIELD_PTR( stmtsToAddAfter , std::list< ast::ptr< ast::Stmt > > )
     287FIELD_PTR( declsToAddBefore, std::list< ast::ptr< ast::Decl > > )
     288FIELD_PTR( declsToAddAfter , std::list< ast::ptr< ast::Decl > > )
     289FIELD_PTR( visit_children, __pass::bool_ref )
     290FIELD_PTR( at_cleanup, __pass::at_cleanup_t )
     291FIELD_PTR( visitor, ast::Pass<core_t> * const )
     292
     293// Remove the macro to make sure we don't clash
     294#undef FIELD_PTR
     295
     296template< typename core_t >
     297static inline auto beginTrace(core_t &, int) -> decltype( core_t::traceId, void() ) {
     298        // Stats::Heap::stacktrace_push(core_t::traceId);
     299}
     300
     301template< typename core_t >
     302static inline auto endTrace(core_t &, int) -> decltype( core_t::traceId, void() ) {
     303        // Stats::Heap::stacktrace_pop();
     304}
     305
     306template< typename core_t >
     307static void beginTrace(core_t &, long) {}
     308
     309template< typename core_t >
     310static void endTrace(core_t &, long) {}
     311
     312// Allows visitor to handle an error on top-level declarations, and possibly suppress the error.
     313// If on_error() returns false, the error will be ignored. By default, it returns true.
     314
     315template< typename core_t >
     316static bool on_error (core_t &, ptr<Decl> &, long) { return true; }
     317
     318template< typename core_t >
     319static auto on_error (core_t & core, ptr<Decl> & decl, int) -> decltype(core.on_error(decl)) {
     320        return core.on_error(decl);
     321}
     322
     323template< typename core_t, typename node_t >
     324static auto make_location_guard( core_t & core, node_t * node, int )
     325                -> decltype( node->location, ValueGuardPtr<const CodeLocation *>( &core.location ) ) {
     326        ValueGuardPtr<const CodeLocation *> guard( &core.location );
     327        core.location = &node->location;
     328        return guard;
     329}
     330
     331template< typename core_t, typename node_t >
     332static auto make_location_guard( core_t &, node_t *, long ) -> int {
     333        return 0;
     334}
     335
     336// Another feature of the templated visitor is that it calls beginScope()/endScope() for compound statement.
     337// All passes which have such functions are assumed desire this behaviour
     338// detect it using the same strategy
     339namespace scope {
     340        template<typename core_t>
     341        static inline auto enter( core_t & core, int ) -> decltype( core.beginScope(), void() ) {
     342                core.beginScope();
     343        }
     344
     345        template<typename core_t>
     346        static inline void enter( core_t &, long ) {}
     347
     348        template<typename core_t>
     349        static inline auto leave( core_t & core, int ) -> decltype( core.endScope(), void() ) {
     350                core.endScope();
     351        }
     352
     353        template<typename core_t>
     354        static inline void leave( core_t &, long ) {}
     355} // namespace scope
     356
     357// Certain passes desire an up to date symbol table automatically
     358// detect the presence of a member name `symtab` and call all the members appropriately
     359namespace symtab {
     360        // Some simple scoping rules
     361        template<typename core_t>
     362        static inline auto enter( core_t & core, int ) -> decltype( core.symtab, void() ) {
     363                core.symtab.enterScope();
     364        }
     365
     366        template<typename core_t>
     367        static inline auto enter( core_t &, long ) {}
     368
     369        template<typename core_t>
     370        static inline auto leave( core_t & core, int ) -> decltype( core.symtab, void() ) {
     371                core.symtab.leaveScope();
     372        }
     373
     374        template<typename core_t>
     375        static inline auto leave( core_t &, long ) {}
     376
     377        // The symbol table has 2 kind of functions mostly, 1 argument and 2 arguments
     378        // Create macro to condense these common patterns
     379        #define SYMTAB_FUNC1( func, type ) \
     380        template<typename core_t> \
     381        static inline auto func( core_t & core, int, type arg ) -> decltype( core.symtab.func( arg ), void() ) {\
     382                core.symtab.func( arg ); \
     383        } \
    284384        \
    285         template< typename core_t > \
    286         static inline default_type * name( core_t &, long ) { return nullptr; }
    287 
    288         // List of fields and their expected types
    289         FIELD_PTR( typeSubs, const ast::TypeSubstitution * )
    290         FIELD_PTR( stmtsToAddBefore, std::list< ast::ptr< ast::Stmt > > )
    291         FIELD_PTR( stmtsToAddAfter , std::list< ast::ptr< ast::Stmt > > )
    292         FIELD_PTR( declsToAddBefore, std::list< ast::ptr< ast::Decl > > )
    293         FIELD_PTR( declsToAddAfter , std::list< ast::ptr< ast::Decl > > )
    294         FIELD_PTR( visit_children, __pass::bool_ref )
    295         FIELD_PTR( at_cleanup, __pass::at_cleanup_t )
    296         FIELD_PTR( visitor, ast::Pass<core_t> * const )
    297 
    298         // Remove the macro to make sure we don't clash
    299         #undef FIELD_PTR
    300 
    301         template< typename core_t >
    302         static inline auto beginTrace(core_t &, int) -> decltype( core_t::traceId, void() ) {
    303                 // Stats::Heap::stacktrace_push(core_t::traceId);
    304         }
    305 
    306         template< typename core_t >
    307         static inline auto endTrace(core_t &, int) -> decltype( core_t::traceId, void() ) {
    308                 // Stats::Heap::stacktrace_pop();
    309         }
    310 
    311         template< typename core_t >
    312         static void beginTrace(core_t &, long) {}
    313 
    314         template< typename core_t >
    315         static void endTrace(core_t &, long) {}
    316 
    317         // Allows visitor to handle an error on top-level declarations, and possibly suppress the error.
    318         // If onError() returns false, the error will be ignored. By default, it returns true.
    319 
    320         template< typename core_t >
    321         static bool on_error (core_t &, ptr<Decl> &, long) { return true; }
    322 
    323         template< typename core_t >
    324         static auto on_error (core_t & core, ptr<Decl> & decl, int) -> decltype(core.on_error(decl)) {
    325                 return core.on_error(decl);
    326         }
    327 
    328         template< typename core_t, typename node_t >
    329         static auto make_location_guard( core_t & core, node_t * node, int )
    330                         -> decltype( node->location, ValueGuardPtr<const CodeLocation *>( &core.location ) ) {
    331                 ValueGuardPtr<const CodeLocation *> guard( &core.location );
    332                 core.location = &node->location;
    333                 return guard;
    334         }
    335 
    336         template< typename core_t, typename node_t >
    337         static auto make_location_guard( core_t &, node_t *, long ) -> int {
    338                 return 0;
    339         }
    340 
    341         // Another feature of the templated visitor is that it calls beginScope()/endScope() for compound statement.
    342         // All passes which have such functions are assumed desire this behaviour
    343         // detect it using the same strategy
    344         namespace scope {
    345                 template<typename core_t>
    346                 static inline auto enter( core_t & core, int ) -> decltype( core.beginScope(), void() ) {
    347                         core.beginScope();
    348                 }
    349 
    350                 template<typename core_t>
    351                 static inline void enter( core_t &, long ) {}
    352 
    353                 template<typename core_t>
    354                 static inline auto leave( core_t & core, int ) -> decltype( core.endScope(), void() ) {
    355                         core.endScope();
    356                 }
    357 
    358                 template<typename core_t>
    359                 static inline void leave( core_t &, long ) {}
    360         } // namespace scope
    361 
    362         // Certain passes desire an up to date symbol table automatically
    363         // detect the presence of a member name `symtab` and call all the members appropriately
    364         namespace symtab {
    365                 // Some simple scoping rules
    366                 template<typename core_t>
    367                 static inline auto enter( core_t & core, int ) -> decltype( core.symtab, void() ) {
    368                         core.symtab.enterScope();
    369                 }
    370 
    371                 template<typename core_t>
    372                 static inline auto enter( core_t &, long ) {}
    373 
    374                 template<typename core_t>
    375                 static inline auto leave( core_t & core, int ) -> decltype( core.symtab, void() ) {
    376                         core.symtab.leaveScope();
    377                 }
    378 
    379                 template<typename core_t>
    380                 static inline auto leave( core_t &, long ) {}
    381 
    382                 // The symbol table has 2 kind of functions mostly, 1 argument and 2 arguments
    383                 // Create macro to condense these common patterns
    384                 #define SYMTAB_FUNC1( func, type ) \
    385                 template<typename core_t> \
    386                 static inline auto func( core_t & core, int, type arg ) -> decltype( core.symtab.func( arg ), void() ) {\
    387                         core.symtab.func( arg ); \
    388                 } \
    389                 \
    390                 template<typename core_t> \
    391                 static inline void func( core_t &, long, type ) {}
    392 
    393                 #define SYMTAB_FUNC2( func, type1, type2 ) \
    394                 template<typename core_t> \
    395                 static inline auto func( core_t & core, int, type1 arg1, type2 arg2 ) -> decltype( core.symtab.func( arg1, arg2 ), void () ) {\
    396                         core.symtab.func( arg1, arg2 ); \
    397                 } \
    398                         \
    399                 template<typename core_t> \
    400                 static inline void func( core_t &, long, type1, type2 ) {}
    401 
    402                 SYMTAB_FUNC1( addId     , const DeclWithType *  );
    403                 SYMTAB_FUNC1( addType   , const NamedTypeDecl * );
    404                 SYMTAB_FUNC1( addStruct , const StructDecl *    );
    405                 SYMTAB_FUNC1( addEnum   , const EnumDecl *      );
    406                 SYMTAB_FUNC1( addUnion  , const UnionDecl *     );
    407                 SYMTAB_FUNC1( addTrait  , const TraitDecl *     );
    408                 SYMTAB_FUNC2( addWith   , const std::vector< ptr<Expr> > &, const Decl * );
    409 
    410                 // A few extra functions have more complicated behaviour, they are hand written
    411                 template<typename core_t>
    412                 static inline auto addStructFwd( core_t & core, int, const ast::StructDecl * decl ) -> decltype( core.symtab.addStruct( decl ), void() ) {
    413                         ast::StructDecl * fwd = new ast::StructDecl( decl->location, decl->name );
    414                         for ( const auto & param : decl->params ) {
    415                                 fwd->params.push_back( deepCopy( param.get() ) );
    416                         }
    417                         core.symtab.addStruct( fwd );
    418                 }
    419 
    420                 template<typename core_t>
    421                 static inline void addStructFwd( core_t &, long, const ast::StructDecl * ) {}
    422 
    423                 template<typename core_t>
    424                 static inline auto addUnionFwd( core_t & core, int, const ast::UnionDecl * decl ) -> decltype( core.symtab.addUnion( decl ), void() ) {
    425                         ast::UnionDecl * fwd = new ast::UnionDecl( decl->location, decl->name );
    426                         for ( const auto & param : decl->params ) {
    427                                 fwd->params.push_back( deepCopy( param.get() ) );
    428                         }
    429                         core.symtab.addUnion( fwd );
    430                 }
    431 
    432                 template<typename core_t>
    433                 static inline void addUnionFwd( core_t &, long, const ast::UnionDecl * ) {}
    434 
    435                 template<typename core_t>
    436                 static inline auto addStruct( core_t & core, int, const std::string & str ) -> decltype( core.symtab.addStruct( str ), void() ) {
    437                         if ( ! core.symtab.lookupStruct( str ) ) {
    438                                 core.symtab.addStruct( str );
    439                         }
    440                 }
    441 
    442                 template<typename core_t>
    443                 static inline void addStruct( core_t &, long, const std::string & ) {}
    444 
    445                 template<typename core_t>
    446                 static inline auto addUnion( core_t & core, int, const std::string & str ) -> decltype( core.symtab.addUnion( str ), void() ) {
    447                         if ( ! core.symtab.lookupUnion( str ) ) {
    448                                 core.symtab.addUnion( str );
    449                         }
    450                 }
    451 
    452                 template<typename core_t>
    453                 static inline void addUnion( core_t &, long, const std::string & ) {}
    454 
    455                 #undef SYMTAB_FUNC1
    456                 #undef SYMTAB_FUNC2
    457         } // namespace symtab
    458 
    459         // Some passes need to mutate TypeDecl and properly update their pointing TypeInstType.
    460         // Detect the presence of a member name `subs` and call all members appropriately
    461         namespace forall {
    462                 // Some simple scoping rules
    463                 template<typename core_t>
    464                 static inline auto enter( core_t & core, int, const ast::FunctionType * type )
    465                 -> decltype( core.subs, void() ) {
    466                         if ( ! type->forall.empty() ) core.subs.beginScope();
    467                 }
    468 
    469                 template<typename core_t>
    470                 static inline auto enter( core_t &, long, const ast::FunctionType * ) {}
    471 
    472                 template<typename core_t>
    473                 static inline auto leave( core_t & core, int, const ast::FunctionType * type )
    474                 -> decltype( core.subs, void() ) {
    475                         if ( ! type->forall.empty() ) { core.subs.endScope(); }
    476                 }
    477 
    478                 template<typename core_t>
    479                 static inline auto leave( core_t &, long, const ast::FunctionType * ) {}
    480 
    481                 // Replaces a TypeInstType's base TypeDecl according to the table
    482                 template<typename core_t>
    483                 static inline auto replace( core_t & core, int, const ast::TypeInstType *& inst )
    484                 -> decltype( core.subs, void() ) {
    485                         inst = ast::mutate_field(
    486                                 inst, &ast::TypeInstType::base, core.subs.replace( inst->base ) );
    487                 }
    488 
    489                 template<typename core_t>
    490                 static inline auto replace( core_t &, long, const ast::TypeInstType *& ) {}
    491         } // namespace forall
    492 
    493         // For passes that need access to the global context. Sreaches `translationUnit`
    494         namespace translation_unit {
    495                 template<typename core_t>
    496                 static inline auto get_cptr( core_t & core, int )
    497                                 -> decltype( &core.translationUnit ) {
    498                         return &core.translationUnit;
    499                 }
    500 
    501                 template<typename core_t>
    502                 static inline const TranslationUnit ** get_cptr( core_t &, long ) {
    503                         return nullptr;
    504                 }
    505         }
    506 
    507         // For passes, usually utility passes, that have a result.
    508         namespace result {
    509                 template<typename core_t>
    510                 static inline auto get( core_t & core, char ) -> decltype( core.result() ) {
    511                         return core.result();
    512                 }
    513 
    514                 template<typename core_t>
    515                 static inline auto get( core_t & core, int ) -> decltype( core.result ) {
    516                         return core.result;
    517                 }
    518 
    519                 template<typename core_t>
    520                 static inline void get( core_t &, long ) {}
    521         }
    522 } // namespace __pass
    523 } // namespace ast
     385        template<typename core_t> \
     386        static inline void func( core_t &, long, type ) {}
     387
     388        #define SYMTAB_FUNC2( func, type1, type2 ) \
     389        template<typename core_t> \
     390        static inline auto func( core_t & core, int, type1 arg1, type2 arg2 ) -> decltype( core.symtab.func( arg1, arg2 ), void () ) {\
     391                core.symtab.func( arg1, arg2 ); \
     392        } \
     393        \
     394        template<typename core_t> \
     395        static inline void func( core_t &, long, type1, type2 ) {}
     396
     397        SYMTAB_FUNC1( addId     , const DeclWithType *  );
     398        SYMTAB_FUNC1( addType   , const NamedTypeDecl * );
     399        SYMTAB_FUNC1( addStruct , const StructDecl *    );
     400        SYMTAB_FUNC1( addEnum   , const EnumDecl *      );
     401        SYMTAB_FUNC1( addUnion  , const UnionDecl *     );
     402        SYMTAB_FUNC1( addTrait  , const TraitDecl *     );
     403        SYMTAB_FUNC2( addWith   , const std::vector< ptr<Expr> > &, const Decl * );
     404
     405        // A few extra functions have more complicated behaviour, they are hand written
     406        template<typename core_t>
     407        static inline auto addStructFwd( core_t & core, int, const ast::StructDecl * decl ) -> decltype( core.symtab.addStruct( decl ), void() ) {
     408                ast::StructDecl * fwd = new ast::StructDecl( decl->location, decl->name );
     409                for ( const auto & param : decl->params ) {
     410                        fwd->params.push_back( deepCopy( param.get() ) );
     411                }
     412                core.symtab.addStruct( fwd );
     413        }
     414
     415        template<typename core_t>
     416        static inline void addStructFwd( core_t &, long, const ast::StructDecl * ) {}
     417
     418        template<typename core_t>
     419        static inline auto addUnionFwd( core_t & core, int, const ast::UnionDecl * decl ) -> decltype( core.symtab.addUnion( decl ), void() ) {
     420                ast::UnionDecl * fwd = new ast::UnionDecl( decl->location, decl->name );
     421                for ( const auto & param : decl->params ) {
     422                        fwd->params.push_back( deepCopy( param.get() ) );
     423                }
     424                core.symtab.addUnion( fwd );
     425        }
     426
     427        template<typename core_t>
     428        static inline void addUnionFwd( core_t &, long, const ast::UnionDecl * ) {}
     429
     430        template<typename core_t>
     431        static inline auto addStruct( core_t & core, int, const std::string & str ) -> decltype( core.symtab.addStruct( str ), void() ) {
     432                if ( ! core.symtab.lookupStruct( str ) ) {
     433                        core.symtab.addStruct( str );
     434                }
     435        }
     436
     437        template<typename core_t>
     438        static inline void addStruct( core_t &, long, const std::string & ) {}
     439
     440        template<typename core_t>
     441        static inline auto addUnion( core_t & core, int, const std::string & str ) -> decltype( core.symtab.addUnion( str ), void() ) {
     442                if ( ! core.symtab.lookupUnion( str ) ) {
     443                        core.symtab.addUnion( str );
     444                }
     445        }
     446
     447        template<typename core_t>
     448        static inline void addUnion( core_t &, long, const std::string & ) {}
     449
     450        #undef SYMTAB_FUNC1
     451        #undef SYMTAB_FUNC2
     452} // namespace symtab
     453
     454// Some passes need to mutate TypeDecl and properly update their pointing TypeInstType.
     455// Detect the presence of a member name `subs` and call all members appropriately
     456namespace forall {
     457        // Some simple scoping rules
     458        template<typename core_t>
     459        static inline auto enter( core_t & core, int, const ast::FunctionType * type )
     460                        -> decltype( core.subs, void() ) {
     461                if ( ! type->forall.empty() ) core.subs.beginScope();
     462        }
     463
     464        template<typename core_t>
     465        static inline auto enter( core_t &, long, const ast::FunctionType * ) {}
     466
     467        template<typename core_t>
     468        static inline auto leave( core_t & core, int, const ast::FunctionType * type )
     469                        -> decltype( core.subs, void() ) {
     470                if ( ! type->forall.empty() ) { core.subs.endScope(); }
     471        }
     472
     473        template<typename core_t>
     474        static inline auto leave( core_t &, long, const ast::FunctionType * ) {}
     475
     476        // Replaces a TypeInstType's base TypeDecl according to the table
     477        template<typename core_t>
     478        static inline auto replace( core_t & core, int, const ast::TypeInstType *& inst )
     479                        -> decltype( core.subs, void() ) {
     480                inst = ast::mutate_field(
     481                        inst, &ast::TypeInstType::base, core.subs.replace( inst->base ) );
     482        }
     483
     484        template<typename core_t>
     485        static inline auto replace( core_t &, long, const ast::TypeInstType *& ) {}
     486} // namespace forall
     487
     488// For passes that need access to the global context. Searches `translationUnit`
     489namespace translation_unit {
     490        template<typename core_t>
     491        static inline auto get_cptr( core_t & core, int )
     492                        -> decltype( &core.translationUnit ) {
     493                return &core.translationUnit;
     494        }
     495
     496        template<typename core_t>
     497        static inline const TranslationUnit ** get_cptr( core_t &, long ) {
     498                return nullptr;
     499        }
     500}
     501
     502// For passes, usually utility passes, that have a result.
     503namespace result {
     504        template<typename core_t>
     505        static inline auto get( core_t & core, char ) -> decltype( core.result() ) {
     506                return core.result();
     507        }
     508
     509        template<typename core_t>
     510        static inline auto get( core_t & core, int ) -> decltype( core.result ) {
     511                return core.result;
     512        }
     513
     514        template<typename core_t>
     515        static inline void get( core_t &, long ) {}
     516}
     517
     518} // namespace ast::__pass
  • src/AST/porting.md

    r1180175 r640b3df  
    213213* `get_statement()` exclusively used for code location, replaced with `CodeLocation` field
    214214
    215 `CaseStmt`
     215`CaseStmt` => `CaseClause`
    216216* `_isDefault` has been removed
    217217  * `isDefault` calculates value from `cond`
     
    227227* `block` -> `body` and `finallyBlock` -> `finally`
    228228
    229 `ThrowStmt` `CatchStmt`
     229`ThrowStmt` and `CatchStmt` => `CatchClause`
    230230* moved `Kind` enums to shared `ast::ExceptionKind` enum
    231231
    232 `FinallyStmt`
     232`FinallyStmt` => `FinallyClause`
    233233* `block` -> `body`
    234234
     
    280280* Template class, with specializations and using to implement some other types:
    281281  * `StructInstType`, `UnionInstType` & `EnumInstType`
     282  * `baseStruct`, `baseUnion` & `baseEnum` => `base`
    282283
    283284`TypeInstType`
  • src/Common/Eval.cc

    r1180175 r640b3df  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // utility.h --
     7// Eval.cc -- Evaluate parts of the ast at compile time.
    88//
    99// Author           : Richard C. Bilson
     
    1313// Update Count     : 119
    1414//
     15
     16#include "Eval.h"
    1517
    1618#include <utility> // for pair
  • src/Common/module.mk

    r1180175 r640b3df  
    2020        Common/CodeLocationTools.hpp \
    2121        Common/CodeLocationTools.cpp \
    22         Common/CompilerError.h \
    2322        Common/Debug.h \
    2423        Common/DeclStats.hpp \
     
    2625        Common/ErrorObjects.h \
    2726        Common/Eval.cc \
     27        Common/Eval.h \
    2828        Common/Examine.cc \
    2929        Common/Examine.h \
     
    3131        Common/Indenter.h \
    3232        Common/Indenter.cc \
     33        Common/Iterate.hpp \
    3334        Common/PassVisitor.cc \
    3435        Common/PassVisitor.h \
     
    5253        Common/Stats/Time.cc \
    5354        Common/Stats/Time.h \
    54         Common/UnimplementedError.h \
    5555        Common/UniqueName.cc \
    5656        Common/UniqueName.h \
  • src/Common/utility.h

    r1180175 r640b3df  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // utility.h --
     7// utility.h -- General utilities used across the compiler.
    88//
    99// Author           : Richard C. Bilson
    1010// Created On       : Mon May 18 07:44:20 2015
    1111// Last Modified By : Andrew Beach
    12 // Last Modified On : Mon Apr 25 14:26:00 2022
    13 // Update Count     : 51
     12// Last Modified On : Fri Feb 17 15:25:00 2023
     13// Update Count     : 53
    1414//
    1515
     
    1919#include <cctype>
    2020#include <algorithm>
    21 #include <functional>
    2221#include <iostream>
    23 #include <iterator>
    2422#include <list>
    2523#include <memory>
     
    2725#include <string>
    2826#include <type_traits>
    29 #include <utility>
    3027#include <vector>
    3128#include <cstring>                                                                              // memcmp
     
    4946                return 0;
    5047        } // if
    51 }
    52 
    53 template< typename T, typename U >
    54 struct maybeBuild_t {
    55         static T * doit( const U *orig ) {
    56                 if ( orig ) {
    57                         return orig->build();
    58                 } else {
    59                         return 0;
    60                 } // if
    61         }
    62 };
    63 
    64 template< typename T, typename U >
    65 static inline T * maybeBuild( const U *orig ) {
    66         return maybeBuild_t<T,U>::doit(orig);
    67 }
    68 
    69 template< typename T, typename U >
    70 static inline T * maybeMoveBuild( const U *orig ) {
    71         T* ret = maybeBuild<T>(orig);
    72         delete orig;
    73         return ret;
    7448}
    7549
     
    189163
    190164#define toCString( ... ) toString( __VA_ARGS__ ).c_str()
    191 
    192 // replace element of list with all elements of another list
    193 template< typename T >
    194 void replace( std::list< T > &org, typename std::list< T >::iterator pos, std::list< T > &with ) {
    195         typename std::list< T >::iterator next = pos; advance( next, 1 );
    196 
    197         //if ( next != org.end() ) {
    198         org.erase( pos );
    199         org.splice( next, with );
    200         //}
    201 
    202         return;
    203 }
    204 
    205 // replace range of a list with a single element
    206 template< typename T >
    207 void replace( std::list< T > &org, typename std::list< T >::iterator begin, typename std::list< T >::iterator end, const T & with ) {
    208         org.insert( begin, with );
    209         org.erase( begin, end );
    210 }
    211165
    212166template< typename... Args >
     
    236190}
    237191
    238 template< typename... Args >
    239 auto zip(Args&&... args) -> decltype(zipWith(std::forward<Args>(args)..., std::make_pair)) {
    240   return zipWith(std::forward<Args>(args)..., std::make_pair);
    241 }
    242 
    243 template< class InputIterator1, class InputIterator2, class OutputIterator, class BinFunction >
    244 void zipWith( InputIterator1 b1, InputIterator1 e1, InputIterator2 b2, InputIterator2 e2, OutputIterator out, BinFunction func ) {
    245         while ( b1 != e1 && b2 != e2 )
    246                 *out++ = func(*b1++, *b2++);
    247 }
    248 
    249 // it's nice to actually be able to increment iterators by an arbitrary amount
    250 template< class InputIt, class Distance >
    251 InputIt operator+( InputIt it, Distance n ) {
    252         advance(it, n);
    253         return it;
    254 }
    255 
    256 template< typename T >
    257 void warn_single( const T & arg ) {
    258         std::cerr << arg << std::endl;
    259 }
    260 
    261 template< typename T, typename... Params >
    262 void warn_single(const T & arg, const Params & ... params ) {
    263         std::cerr << arg;
    264         warn_single( params... );
    265 }
    266 
    267192template< typename... Params >
    268193void warn( const Params & ... params ) {
    269194        std::cerr << "Warning: ";
    270         warn_single( params... );
     195        toString_single( std::cerr, params... );
     196        std::cerr << std::endl;
    271197}
    272198
     
    274200static inline bool isPrefix( const std::string & str, const std::string & pref, unsigned int start = 0 ) {
    275201        if ( pref.size() > str.size() ) return false;
    276     return 0 == memcmp( str.c_str() + start, pref.c_str(), pref.size() );
    277         // return prefix == full.substr(0, prefix.size()); // for future, requires c++17
    278 }
    279 
    280 // -----------------------------------------------------------------------------
    281 // Ref Counted Singleton class
    282 // Objects that inherit from this class will have at most one reference to it
    283 // but if all references die, the object will be deleted.
    284 
    285 template< typename ThisType >
    286 class RefCountSingleton {
    287   public:
    288         static std::shared_ptr<ThisType> get() {
    289                 if( global_instance.expired() ) {
    290                         std::shared_ptr<ThisType> new_instance = std::make_shared<ThisType>();
    291                         global_instance = new_instance;
    292                         return std::move(new_instance);
    293                 }
    294                 return global_instance.lock();
    295         }
    296   private:
    297         static std::weak_ptr<ThisType> global_instance;
    298 };
    299 
    300 template< typename ThisType >
    301 std::weak_ptr<ThisType> RefCountSingleton<ThisType>::global_instance;
     202        return pref == str.substr(start, pref.size());
     203}
    302204
    303205// -----------------------------------------------------------------------------
     
    356258        ~ValueGuardPtr() { if( ref ) { swap( *ref, old ); } }
    357259};
    358 
    359 // -----------------------------------------------------------------------------
    360 // Helper struct and function to support
    361 // for ( val : reverseIterate( container ) ) {}
    362 // syntax to have a for each that iterates backwards
    363 
    364 template< typename T >
    365 struct reverse_iterate_t {
    366         T& ref;
    367 
    368         reverse_iterate_t( T & ref ) : ref(ref) {}
    369 
    370         // this does NOT work on const T!!!
    371         // typedef typename T::reverse_iterator iterator;
    372         auto begin() { return ref.rbegin(); }
    373         auto end() { return ref.rend(); }
    374 };
    375 
    376 template< typename T >
    377 reverse_iterate_t< T > reverseIterate( T & ref ) {
    378         return reverse_iterate_t< T >( ref );
    379 }
    380 
    381 template< typename T >
    382 struct enumerate_t {
    383         template<typename val_t>
    384         struct value_t {
    385                 val_t & val;
    386                 size_t idx;
    387         };
    388 
    389         template< typename iter_t, typename val_t >
    390         struct iterator_t {
    391                 iter_t it;
    392                 size_t idx;
    393 
    394                 iterator_t( iter_t _it, size_t _idx ) : it(_it), idx(_idx) {}
    395 
    396                 value_t<val_t> operator*() const { return value_t<val_t>{ *it, idx }; }
    397 
    398                 bool operator==(const iterator_t & o) const { return o.it == it; }
    399                 bool operator!=(const iterator_t & o) const { return o.it != it; }
    400 
    401                 iterator_t & operator++() {
    402                         it++;
    403                         idx++;
    404                         return *this;
    405                 }
    406 
    407                 using difference_type   = typename std::iterator_traits< iter_t >::difference_type;
    408                 using value_type        = value_t<val_t>;
    409                 using pointer           = value_t<val_t> *;
    410                 using reference         = value_t<val_t> &;
    411                 using iterator_category = std::forward_iterator_tag;
    412         };
    413 
    414         T & ref;
    415 
    416         using iterator = iterator_t< typename T::iterator, typename T::value_type >;
    417         using const_iterator = iterator_t< typename T::const_iterator, const typename T::value_type >;
    418 
    419         iterator begin() { return iterator( ref.begin(), 0 ); }
    420         iterator end()   { return iterator( ref.end(), ref.size() ); }
    421 
    422         const_iterator begin() const { return const_iterator( ref.cbegin(), 0 ); }
    423         const_iterator end()   const { return const_iterator( ref.cend(), ref.size() ); }
    424 
    425         const_iterator cbegin() const { return const_iterator( ref.cbegin(), 0 ); }
    426         const_iterator cend()   const { return const_iterator( ref.cend(), ref.size() ); }
    427 };
    428 
    429 template< typename T >
    430 enumerate_t<T> enumerate( T & ref ) {
    431         return enumerate_t< T >{ ref };
    432 }
    433 
    434 template< typename T >
    435 const enumerate_t< const T > enumerate( const T & ref ) {
    436         return enumerate_t< const T >{ ref };
    437 }
    438 
    439 template< typename OutType, typename Range, typename Functor >
    440 OutType map_range( const Range& range, Functor&& functor ) {
    441         OutType out;
    442 
    443         std::transform(
    444                 begin( range ),
    445                 end( range ),
    446                 std::back_inserter( out ),
    447                 std::forward< Functor >( functor )
    448         );
    449 
    450         return out;
    451 }
    452 
    453 // -----------------------------------------------------------------------------
    454 // Helper struct and function to support:
    455 // for ( auto val : group_iterate( container1, container2, ... ) ) { ... }
    456 // This iteraters through multiple containers of the same size.
    457 
    458 template<typename... Args>
    459 class group_iterate_t {
    460         using Iterables = std::tuple<Args...>;
    461         Iterables iterables;
    462 
    463         // Getting the iterator and value types this way preserves const.
    464         template<size_t I> using Iter = decltype(std::get<I>(iterables).begin());
    465         template<size_t I> using Data = decltype(*std::get<I>(iterables).begin());
    466         template<typename> struct base_iterator;
    467 
    468         // This inner template puts the sequence of `0, 1, ... sizeof...(Args)-1`
    469         // into a pack. These are the indexes into the tuples, so unpacking can
    470         // go over each element of the tuple.
    471         // The std::integer_sequence is just used to build that sequence.
    472         // A library reference will probably explain it better than I can.
    473         template<std::size_t... Indices>
    474         struct base_iterator<std::integer_sequence<std::size_t, Indices...>> {
    475                 using value_type = std::tuple< Data<Indices>... >;
    476                 std::tuple<Iter<Indices>...> iterators;
    477 
    478                 base_iterator( Iter<Indices>... is ) : iterators( is... ) {}
    479                 base_iterator operator++() {
    480                         return base_iterator( ++std::get<Indices>( iterators )... );
    481                 }
    482                 bool operator!=( const base_iterator& other ) const {
    483                         return iterators != other.iterators;
    484                 }
    485                 value_type operator*() const {
    486                         return std::tie( *std::get<Indices>( iterators )... );
    487                 }
    488 
    489                 static base_iterator make_begin( Iterables & data ) {
    490                         return base_iterator( std::get<Indices>( data ).begin()... );
    491                 }
    492                 static base_iterator make_end( Iterables & data ) {
    493                         return base_iterator( std::get<Indices>( data ).end()... );
    494                 }
    495         };
    496 
    497 public:
    498         group_iterate_t( const Args &... args ) : iterables( args... ) {}
    499 
    500         using iterator = base_iterator<decltype(
    501                 std::make_integer_sequence<std::size_t, sizeof...(Args)>())>;
    502 
    503         iterator begin() { return iterator::make_begin( iterables ); }
    504         iterator end() { return iterator::make_end( iterables ); }
    505 };
    506 
    507 // Helpers for the bounds checks (the non-varatic part of group_iterate):
    508 static inline void runGroupBoundsCheck(size_t size0, size_t size1) {
    509         assertf( size0 == size1,
    510                 "group iteration requires containers of the same size: <%zd, %zd>.",
    511                 size0, size1 );
    512 }
    513 
    514 static inline void runGroupBoundsCheck(size_t size0, size_t size1, size_t size2) {
    515         assertf( size0 == size1 && size1 == size2,
    516                 "group iteration requires containers of the same size: <%zd, %zd, %zd>.",
    517                 size0, size1, size2 );
    518 }
    519 
    520 /// Performs bounds check to ensure that all arguments are of the same length.
    521 template< typename... Args >
    522 group_iterate_t<Args...> group_iterate( Args &&... args ) {
    523         runGroupBoundsCheck( args.size()... );
    524         return group_iterate_t<Args...>( std::forward<Args>( args )... );
    525 }
    526 
    527 /// Does not perform a bounds check - requires user to ensure that iteration terminates when appropriate.
    528 template< typename... Args >
    529 group_iterate_t<Args...> unsafe_group_iterate( Args &&... args ) {
    530         return group_iterate_t<Args...>( std::forward<Args>( args )... );
    531 }
    532 
    533 // -----------------------------------------------------------------------------
    534 // Helper struct and function to support
    535 // for ( val : lazy_map( container1, f ) ) {}
    536 // syntax to have a for each that iterates a container, mapping each element by applying f
    537 template< typename T, typename Func >
    538 struct lambda_iterate_t {
    539         const T & ref;
    540         std::function<Func> f;
    541 
    542         struct iterator {
    543                 typedef decltype(begin(ref)) Iter;
    544                 Iter it;
    545                 std::function<Func> f;
    546                 iterator( Iter it, std::function<Func> f ) : it(it), f(f) {}
    547                 iterator & operator++() {
    548                         ++it; return *this;
    549                 }
    550                 bool operator!=( const iterator &other ) const { return it != other.it; }
    551                 auto operator*() const -> decltype(f(*it)) { return f(*it); }
    552         };
    553 
    554         lambda_iterate_t( const T & ref, std::function<Func> f ) : ref(ref), f(f) {}
    555 
    556         auto begin() const -> decltype(iterator(std::begin(ref), f)) { return iterator(std::begin(ref), f); }
    557         auto end() const   -> decltype(iterator(std::end(ref), f)) { return iterator(std::end(ref), f); }
    558 };
    559 
    560 template< typename... Args >
    561 lambda_iterate_t<Args...> lazy_map( const Args &... args ) {
    562         return lambda_iterate_t<Args...>( args...);
    563 }
    564260
    565261// -----------------------------------------------------------------------------
     
    583279} // ilog2
    584280
    585 // -----------------------------------------------------------------------------
    586 /// evaluates expr as a long long int. If second is false, expr could not be evaluated
    587 std::pair<long long int, bool> eval(const Expression * expr);
    588 
    589 namespace ast {
    590         class Expr;
    591 }
    592 
    593 std::pair<long long int, bool> eval(const ast::Expr * expr);
    594 
    595 // -----------------------------------------------------------------------------
    596 /// Reorders the input range in-place so that the minimal-value elements according to the
    597 /// comparator are in front;
    598 /// returns the iterator after the last minimal-value element.
    599 template<typename Iter, typename Compare>
    600 Iter sort_mins( Iter begin, Iter end, Compare& lt ) {
    601         if ( begin == end ) return end;
    602 
    603         Iter min_pos = begin;
    604         for ( Iter i = begin + 1; i != end; ++i ) {
    605                 if ( lt( *i, *min_pos ) ) {
    606                         // new minimum cost; swap into first position
    607                         min_pos = begin;
    608                         std::iter_swap( min_pos, i );
    609                 } else if ( ! lt( *min_pos, *i ) ) {
    610                         // duplicate minimum cost; swap into next minimum position
    611                         ++min_pos;
    612                         std::iter_swap( min_pos, i );
    613                 }
    614         }
    615         return ++min_pos;
    616 }
    617 
    618 template<typename Iter, typename Compare>
    619 inline Iter sort_mins( Iter begin, Iter end, Compare&& lt ) {
    620         return sort_mins( begin, end, lt );
    621 }
    622 
    623 /// sort_mins defaulted to use std::less
    624 template<typename Iter>
    625 inline Iter sort_mins( Iter begin, Iter end ) {
    626         return sort_mins( begin, end, std::less<typename std::iterator_traits<Iter>::value_type>{} );
    627 }
    628 
    629281// Local Variables: //
    630282// tab-width: 4 //
  • src/GenPoly/Box.cc

    r1180175 r640b3df  
    8080                        CallAdapter();
    8181
     82                        void premutate( Declaration * declaration );
    8283                        void premutate( FunctionDecl * functionDecl );
    8384                        void premutate( TypeDecl * typeDecl );
     
    454455
    455456                CallAdapter::CallAdapter() : tempNamer( "_temp" ) {}
     457
     458                void CallAdapter::premutate( Declaration * ) {
     459                        // Prevent type declaration information from leaking out.
     460                        GuardScope( scopeTyVars );
     461                }
    456462
    457463                void CallAdapter::premutate( FunctionDecl *functionDecl ) {
  • src/GenPoly/FindFunction.cc

    r1180175 r640b3df  
    99// Author           : Richard C. Bilson
    1010// Created On       : Mon May 18 07:44:20 2015
    11 // Last Modified By : Rob Schluntz
    12 // Last Modified On : Fri Feb 05 12:22:20 2016
    13 // Update Count     : 6
     11// Last Modified By : Andrew Beach
     12// Last Modified On : Fri Oct  7 17:05:20 2022
     13// Update Count     : 7
    1414//
    1515
     
    1818#include <utility>                      // for pair
    1919
     20#include "AST/Pass.hpp"                 // for Pass
     21#include "AST/Type.hpp"
    2022#include "Common/PassVisitor.h"         // for PassVisitor
    2123#include "GenPoly/ErasableScopedMap.h"  // for ErasableScopedMap<>::iterator
     
    8991                handleForall( pointerType->get_forall() );
    9092        }
     93
     94namespace {
     95
     96struct FindFunctionCore :
     97                public ast::WithGuards,
     98                public ast::WithShortCircuiting,
     99                public ast::WithVisitorRef<FindFunctionCore> {
     100        FindFunctionCore(
     101                std::vector<ast::ptr<ast::FunctionType>> & functions,
     102                const TypeVarMap & typeVars, FindFunctionPred predicate,
     103                bool replaceMode );
     104
     105        void previsit( ast::FunctionType const * type );
     106        ast::Type const * postvisit( ast::FunctionType const * type );
     107        void previsit( ast::PointerType const * type );
     108private:
     109        void handleForall( const ast::FunctionType::ForallList & forall );
     110
     111        std::vector<ast::ptr<ast::FunctionType>> &functions;
     112        TypeVarMap typeVars;
     113        FindFunctionPred predicate;
     114        bool replaceMode;
     115};
     116
     117FindFunctionCore::FindFunctionCore(
     118                std::vector<ast::ptr<ast::FunctionType>> & functions,
     119                const TypeVarMap &typeVars, FindFunctionPred predicate,
     120                bool replaceMode ) :
     121        functions( functions ), typeVars( typeVars ),
     122        predicate( predicate ), replaceMode( replaceMode ) {}
     123
     124void FindFunctionCore::handleForall( const ast::FunctionType::ForallList & forall ) {
     125        for ( const ast::ptr<ast::TypeInstType> & td : forall ) {
     126                TypeVarMap::iterator var = typeVars.find( *td );
     127                if ( var != typeVars.end() ) {
     128                        typeVars.erase( var->first );
     129                } // if
     130        } // for
     131}
     132
     133void FindFunctionCore::previsit( ast::FunctionType const * type ) {
     134        visit_children = false;
     135        GuardScope( typeVars );
     136        handleForall( type->forall );
     137        //ast::accept_all( type->returns, *visitor );
     138        // This might have to become ast::mutate_each with return.
     139        ast::accept_each( type->returns, *visitor );
     140}
     141
     142ast::Type const * FindFunctionCore::postvisit( ast::FunctionType const * type ) {
     143        ast::Type const * ret = type;
     144        if ( predicate( type, typeVars ) ) {
     145                functions.push_back( type );
     146                if ( replaceMode ) {
     147                        // replace type parameters in function type with void*
     148                        ret = scrubTypeVars( ast::deepCopy( type ), typeVars );
     149                } // if
     150        } // if
     151        return ret;
     152}
     153
     154void FindFunctionCore::previsit( ast::PointerType const * /*type*/ ) {
     155        GuardScope( typeVars );
     156        //handleForall( type->forall );
     157}
     158
     159} // namespace
     160
     161void findFunction( const ast::Type * type,
     162                std::vector<ast::ptr<ast::FunctionType>> & functions,
     163                const TypeVarMap & typeVars, FindFunctionPred predicate ) {
     164        ast::Pass<FindFunctionCore> pass( functions, typeVars, predicate, false );
     165        type->accept( pass );
     166        //(void)type;
     167        //(void)functions;
     168        //(void)typeVars;
     169        //(void)predicate;
     170}
     171
     172const ast::Type * findAndReplaceFunction( const ast::Type * type,
     173                std::vector<ast::ptr<ast::FunctionType>> & functions,
     174                const TypeVarMap & typeVars, FindFunctionPred predicate ) {
     175        ast::Pass<FindFunctionCore> pass( functions, typeVars, predicate, true );
     176        return type->accept( pass );
     177        //(void)functions;
     178        //(void)typeVars;
     179        //(void)predicate;
     180        //return type;
     181}
     182
    91183} // namespace GenPoly
    92184
  • src/GenPoly/FindFunction.h

    r1180175 r640b3df  
    99// Author           : Richard C. Bilson
    1010// Created On       : Mon May 18 07:44:20 2015
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sat Jul 22 09:23:36 2017
    13 // Update Count     : 2
     11// Last Modified By : Andrew Beach
     12// Last Modified On : Fri Oct  7 10:30:00 2022
     13// Update Count     : 3
    1414//
    1515
     
    3030        /// like `findFunction`, but also replaces the function type with void ()(void)
    3131        void findAndReplaceFunction( Type *&type, std::list< FunctionType const * > &functions, const TyVarMap &tyVars, FindFunctionPredicate predicate );
     32
     33typedef bool (*FindFunctionPred)( const ast::FunctionType *, const TypeVarMap & );
     34
     35/// Recursively walks `type`, placing all functions that match `predicate`
     36/// under `typeVars` into `functions`.
     37void findFunction( const ast::Type * type,
     38                std::vector<ast::ptr<ast::FunctionType>> & functions,
     39                const TypeVarMap & typeVars, FindFunctionPred predicate );
     40/// Like findFunction, but also replaces the function type with `void ()(void)`.
     41const ast::Type * findAndReplaceFunction( const ast::Type * type,
     42                std::vector<ast::ptr<ast::FunctionType>> & functions,
     43                const TypeVarMap & typeVars, FindFunctionPred predicate );
     44
    3245} // namespace GenPoly
    3346
  • src/GenPoly/GenPoly.cc

    r1180175 r640b3df  
    275275        }
    276276
     277const ast::BaseInstType *isDynRet( const ast::FunctionType * func ) {
     278        if ( func->returns.empty() ) return nullptr;
     279
     280        TypeVarMap forallTypes = { ast::TypeData() };
     281        makeTypeVarMap( func, forallTypes );
     282        return isDynType( func->returns.front(), forallTypes );
     283}
     284
    277285        bool needsAdapter( FunctionType *adaptee, const TyVarMap &tyVars ) {
    278286//              if ( ! adaptee->get_returnVals().empty() && isPolyType( adaptee->get_returnVals().front()->get_type(), tyVars ) ) {
     
    319327                return 0;
    320328        }
     329
     330const ast::Type * isPolyPtr(
     331                const ast::Type * type, const TypeVarMap & typeVars,
     332                const ast::TypeSubstitution * typeSubs ) {
     333        type = replaceTypeInst( type, typeSubs );
     334
     335        if ( auto * ptr = dynamic_cast<ast::PointerType const *>( type ) ) {
     336                return isPolyType( ptr->base, typeVars, typeSubs );
     337        }
     338        return nullptr;
     339}
    321340
    322341        Type * hasPolyBase( Type *type, int *levels, const TypeSubstitution *env ) {
     
    796815        }
    797816
     817void addToTypeVarMap( const ast::TypeDecl * decl, TypeVarMap & typeVars ) {
     818        typeVars.insert( ast::TypeEnvKey( decl, 0, 0 ), ast::TypeData( decl ) );
     819}
     820
    798821void addToTypeVarMap( const ast::TypeInstType * type, TypeVarMap & typeVars ) {
    799         typeVars.insert( *type, ast::TypeData( type->base ) );
     822        typeVars.insert( ast::TypeEnvKey( *type ), ast::TypeData( type->base ) );
    800823}
    801824
     
    822845}
    823846
     847void makeTypeVarMap( const ast::FunctionDecl * decl, TypeVarMap & typeVars ) {
     848        for ( auto & typeDecl : decl->type_params ) {
     849                addToTypeVarMap( typeDecl, typeVars );
     850        }
     851}
     852
    824853        void printTyVarMap( std::ostream &os, const TyVarMap &tyVarMap ) {
    825854                for ( TyVarMap::const_iterator i = tyVarMap.begin(); i != tyVarMap.end(); ++i ) {
  • src/GenPoly/GenPoly.h

    r1180175 r640b3df  
    111111        void addToTyVarMap( TypeDecl * tyVar, TyVarMap &tyVarMap );
    112112        void addToTypeVarMap( const ast::TypeDecl * type, TypeVarMap & typeVars );
     113        void addToTypeVarMap( const ast::TypeInstType * type, TypeVarMap & typeVars );
    113114
    114115        /// Adds the declarations in the forall list of type (and its pointed-to type if it's a pointer type) to `tyVarMap`
    115116        void makeTyVarMap( Type *type, TyVarMap &tyVarMap );
    116117        void makeTypeVarMap( const ast::Type * type, TypeVarMap & typeVars );
     118        void makeTypeVarMap( const ast::FunctionDecl * decl, TypeVarMap & typeVars );
    117119
    118120        /// Prints type variable map
  • src/Parser/DeclarationNode.cc

    r1180175 r640b3df  
    1010// Created On       : Sat May 16 12:34:05 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Mon Aug  8 17:07:00 2022
    13 // Update Count     : 1185
     12// Last Modified On : Thu Feb 16 14:12:03 2023
     13// Update Count     : 1388
    1414//
    1515
     
    6161        variable.initializer = nullptr;
    6262
    63 //      attr.name = nullptr;
    64         attr.expr = nullptr;
    65         attr.type = nullptr;
    66 
    6763        assert.condition = nullptr;
    6864        assert.message = nullptr;
     
    7066
    7167DeclarationNode::~DeclarationNode() {
    72 //      delete attr.name;
    73         delete attr.expr;
    74         delete attr.type;
    75 
    7668//      delete variable.name;
    7769        delete variable.assertions;
     
    115107        newnode->variable.initializer = maybeClone( variable.initializer );
    116108
    117 //      newnode->attr.name = attr.name ? new string( *attr.name ) : nullptr;
    118         newnode->attr.expr = maybeClone( attr.expr );
    119         newnode->attr.type = maybeClone( attr.type );
    120 
    121109        newnode->assert.condition = maybeClone( assert.condition );
    122110        newnode->assert.message = maybeClone( assert.message );
     
    154142        } // if
    155143
    156         for ( Attribute * attr: reverseIterate( attributes ) ) {
    157                 os << string( indent + 2, ' ' ) << "attr " << attr->name.c_str();
    158         } // for
     144        if ( ! attributes.empty() ) {
     145                os << string( indent + 2, ' ' ) << "with attributes " << endl;
     146                for ( Attribute * attr: reverseIterate( attributes ) ) {
     147                        os << string( indent + 4, ' ' ) << attr->name.c_str() << endl;
     148                } // for
     149        } // if
    159150
    160151        os << endl;
     
    244235        newnode->type = new TypeData( TypeData::Aggregate );
    245236        newnode->type->aggregate.kind = kind;
    246         newnode->type->aggregate.name = name == nullptr ? new string( DeclarationNode::anonymous.newName() ) : name;
     237        newnode->type->aggregate.anon = name == nullptr;
     238        newnode->type->aggregate.name = newnode->type->aggregate.anon ? new string( DeclarationNode::anonymous.newName() ) : name;
    247239        newnode->type->aggregate.actuals = actuals;
    248240        newnode->type->aggregate.fields = fields;
     
    250242        newnode->type->aggregate.tagged = false;
    251243        newnode->type->aggregate.parent = nullptr;
    252         newnode->type->aggregate.anon = name == nullptr;
    253244        return newnode;
    254245} // DeclarationNode::newAggregate
     
    257248        DeclarationNode * newnode = new DeclarationNode;
    258249        newnode->type = new TypeData( TypeData::Enum );
    259         newnode->type->enumeration.name = name == nullptr ? new string( DeclarationNode::anonymous.newName() ) : name;
     250        newnode->type->enumeration.anon = name == nullptr;
     251        newnode->type->enumeration.name = newnode->type->enumeration.anon ? new string( DeclarationNode::anonymous.newName() ) : name;
    260252        newnode->type->enumeration.constants = constants;
    261253        newnode->type->enumeration.body = body;
    262         newnode->type->enumeration.anon = name == nullptr;
    263254        newnode->type->enumeration.typed = typed;
    264255        newnode->type->enumeration.hiding = hiding;
     
    989980        for ( const DeclarationNode * cur = firstNode; cur; cur = dynamic_cast< DeclarationNode * >( cur->get_next() ) ) {
    990981                try {
    991                         bool extracted = false;
    992                         bool anon = false;
     982                        bool extracted = false, anon = false;
     983                        AggregateDecl * unionDecl = nullptr;
     984
    993985                        if ( DeclarationNode * extr = cur->extractAggregate() ) {
    994986                                // handle the case where a structure declaration is contained within an object or type declaration
     987
    995988                                Declaration * decl = extr->build();
    996989                                if ( decl ) {
    997                                         // hoist the structure declaration
     990                                        // Remember the declaration if it is a union aggregate ?
     991                                        unionDecl = dynamic_cast<UnionDecl *>( decl );
     992
    998993                                        decl->location = cur->location;
    999                                         * out++ = decl;
     994                                        *out++ = decl;
    1000995
    1001996                                        // need to remember the cases where a declaration contains an anonymous aggregate definition
     
    1003998                                        assert( extr->type );
    1004999                                        if ( extr->type->kind == TypeData::Aggregate ) {
     1000                                                // typedef struct { int A } B is the only case?
    10051001                                                anon = extr->type->aggregate.anon;
    10061002                                        } else if ( extr->type->kind == TypeData::Enum ) {
    1007                                                 // xxx - is it useful to have an implicit anonymous enum member?
     1003                                                // typedef enum { A } B is the only case?
    10081004                                                anon = extr->type->enumeration.anon;
    10091005                                        }
     
    10141010                        Declaration * decl = cur->build();
    10151011                        if ( decl ) {
     1012                                if ( TypedefDecl * typedefDecl = dynamic_cast<TypedefDecl *>( decl ) ) {
     1013                                        if ( unionDecl ) {                                      // is the typedef alias a union aggregate ?
     1014                                                // This code handles a special issue with the attribute transparent_union.
     1015                                                //
     1016                                                //    typedef union U { int i; } typedef_name __attribute__(( aligned(16) )) __attribute__(( transparent_union ))
     1017                                                //
     1018                                                // Here the attribute aligned goes with the typedef_name, so variables declared of this type are
     1019                                                // aligned.  However, the attribute transparent_union must be moved from the typedef_name to
     1020                                                // alias union U.  Currently, this is the only know attribute that must be moved from typedef to
     1021                                                // alias.
     1022
     1023                                                // If typedef is an alias for a union, then its alias type was hoisted above and remembered.
     1024                                                if ( UnionInstType * unionInstType = dynamic_cast<UnionInstType *>( typedefDecl->base ) ) {
     1025                                                        // Remove all transparent_union attributes from typedef and move to alias union.
     1026                                                        list<Attribute *>::iterator attr;
     1027                                                        for ( attr = unionInstType->attributes.begin(); attr != unionInstType->attributes.end(); ) { // forward order
     1028                                                                if ( (*attr)->name == "transparent_union" || (*attr)->name == "__transparent_union__" ) {
     1029                                                                        list<Attribute *>::iterator cur = attr; // remember current node
     1030                                                                        attr++;                         // advance iterator
     1031                                                                        unionDecl->attributes.emplace_back( *cur ); // move current
     1032                                                                        unionInstType->attributes.erase( cur ); // remove current
     1033                                                                } else {
     1034                                                                        attr++;                         // advance iterator
     1035                                                                } // if
     1036                                                        } // for
     1037                                                } // if
     1038                                        } // if
     1039                                } // if
     1040
    10161041                                // don't include anonymous declaration for named aggregates, but do include them for anonymous aggregates, e.g.:
    10171042                                // struct S {
     
    11761201        assert( type );
    11771202
    1178         if ( attr.expr ) {
    1179                 return new AttrType( buildQualifiers( type ), *name, attr.expr->build(), attributes );
    1180         } else if ( attr.type ) {
    1181                 return new AttrType( buildQualifiers( type ), *name, attr.type->buildType(), attributes );
    1182         } // if
    1183 
    11841203        switch ( type->kind ) {
    11851204          case TypeData::Enum:
  • src/Parser/ExpressionNode.cc

    r1180175 r640b3df  
    1010// Created On       : Sat May 16 13:17:07 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sat Aug  7 09:18:56 2021
    13 // Update Count     : 1077
     12// Last Modified On : Sat Feb 11 14:49:00 2023
     13// Update Count     : 1079
    1414//
    1515
     
    173173                if ( posn != string::npos ) { Unsigned = true; type = 2; ltype = 4; str.erase( posn, 1 ); goto FINI; }
    174174
    175                 posn = str.rfind( "hh" );                                               // char
     175                posn = str.rfind( "hh" );                                               // signed char
    176176                if ( posn != string::npos ) { type = 1; str.erase( posn, 2 ); goto FINI; }
    177177
    178                 posn = str.rfind( "HH" );                                               // char
     178                posn = str.rfind( "HH" );                                               // signed char
    179179                if ( posn != string::npos ) { type = 1; str.erase( posn, 2 ); goto FINI; }
    180180
     
    592592Expression * build_unary_ptr( OperKinds op, ExpressionNode * expr_node ) {
    593593        list< Expression * > args;
    594         args.push_back(  maybeMoveBuild< Expression >(expr_node) ); // xxx -- this is exactly the same as the val case now, refactor this code.
     594        args.push_back( maybeMoveBuild< Expression >(expr_node) ); // xxx -- this is exactly the same as the val case now, refactor this code.
    595595        return new UntypedExpr( new NameExpr( OperName[ (int)op ] ), args );
    596596} // build_unary_ptr
  • src/Parser/ParseNode.h

    r1180175 r640b3df  
    1010// Created On       : Sat May 16 13:28:16 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Wed Nov  2 21:27:07 2022
    13 // Update Count     : 939
     12// Last Modified On : Sun Feb 19 09:02:37 2023
     13// Update Count     : 940
    1414//
    1515
     
    2727#include "Common/SemanticError.h"  // for SemanticError
    2828#include "Common/UniqueName.h"     // for UniqueName
    29 #include "Common/utility.h"        // for maybeClone, maybeBuild
     29#include "Common/utility.h"        // for maybeClone
     30#include "Parser/parserutility.h"  // for maybeBuild
    3031#include "SynTree/LinkageSpec.h"   // for Spec
    3132#include "SynTree/Declaration.h"   // for Aggregate
     
    324325        Variable_t variable;
    325326
    326         struct Attr_t {
    327 //              const std::string * name;
    328                 ExpressionNode * expr;
    329                 DeclarationNode * type;
    330         };
    331         Attr_t attr;
    332 
    333327        struct StaticAssert_t {
    334328                ExpressionNode * condition;
     
    342336
    343337        bool inLine = false;
    344         bool enumInLine = false; 
     338        bool enumInLine = false;
    345339        Type::FuncSpecifiers funcSpecs;
    346340        Type::StorageClasses storageClasses;
  • src/Parser/RunParser.cpp

    r1180175 r640b3df  
    1010// Created On       : Mon Dec 19 11:00:00 2022
    1111// Last Modified By : Andrew Beach
    12 // Last Modified On : Thr Dec 22 10:18:00 2022
    13 // Update Count     : 1
     12// Last Modified On : Thr Feb 16 10:08:00 2023
     13// Update Count     : 2
    1414//
    1515
     
    2424
    2525// Variables global to the parsing code.
    26 LinkageSpec::Spec linkage = LinkageSpec::Cforall;
     26ast::Linkage::Spec linkage = ast::Linkage::Cforall;
    2727TypedefTable typedefTable;
    2828DeclarationNode * parseTree = nullptr;
    2929
    30 void parse( FILE * input, LinkageSpec::Spec linkage, bool alwaysExit ) {
     30void parse( FILE * input, ast::Linkage::Spec linkage, bool alwaysExit ) {
    3131        extern int yyparse( void );
    3232        extern FILE * yyin;
  • src/Parser/RunParser.hpp

    r1180175 r640b3df  
    1010// Created On       : Mon Dec 19 10:42:00 2022
    1111// Last Modified By : Andrew Beach
    12 // Last Modified On : Thr Dec 22 10:23:00 2022
    13 // Update Count     : 1
     12// Last Modified On : Thr Feb 16 10:08:00 2023
     13// Update Count     : 2
    1414//
    1515
     
    1818#include <iosfwd>                           // for ostream
    1919
    20 #include "SynTree/LinkageSpec.h"            // for Spec
     20#include "AST/LinkageSpec.hpp"              // for Spec
    2121namespace ast {
    2222        class TranslationUnit;
     
    2929/// The input file is closed when complete. Exits instead of returning on
    3030/// error or if alwaysExit is true.
    31 void parse( FILE * input, LinkageSpec::Spec linkage, bool alwaysExit = false );
     31void parse( FILE * input, ast::Linkage::Spec linkage, bool alwaysExit = false );
    3232
    3333/// Drain the internal accumulator of parsed code and build a translation
  • src/Parser/TypeData.cc

    r1180175 r640b3df  
    1010// Created On       : Sat May 16 15:12:51 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Tue May 10 22:36:52 2022
    13 // Update Count     : 677
     12// Last Modified On : Sun Feb 19 11:00:46 2023
     13// Update Count     : 679
    1414//
    1515
     
    375375                break;
    376376          case Enum:
    377                 os << "enumeration ";
     377                os << "enumeration " << *enumeration.name << endl;;
    378378                if ( enumeration.constants ) {
    379379                        os << "with constants" << endl;
  • src/Parser/TypeData.h

    r1180175 r640b3df  
    1010// Created On       : Sat May 16 15:18:36 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Tue May 10 22:18:49 2022
    13 // Update Count     : 203
     12// Last Modified On : Sun Feb 19 09:09:39 2023
     13// Update Count     : 204
    1414//
    1515
     
    3737                bool body;
    3838                bool anon;
    39 
    4039                bool tagged;
    4140                const std::string * parent = nullptr;
  • src/Parser/parser.yy

    r1180175 r640b3df  
    1010// Created On       : Sat Sep  1 20:22:55 2001
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Feb  2 21:36:16 2023
    13 // Update Count     : 5865
     12// Last Modified On : Mon Feb 20 11:31:26 2023
     13// Update Count     : 5896
    1414//
    1515
     
    5555#include "Common/utility.h"                                                             // for maybeMoveBuild, maybeBuild, CodeLo...
    5656
    57 #include "SynTree/Attribute.h"     // for Attribute
     57#include "SynTree/Attribute.h"                                                  // for Attribute
    5858
    5959// lex uses __null in a boolean context, it's fine.
     
    19511951                {
    19521952                        typedefTable.addToEnclosingScope( *$4->name, TYPEDEFname, "6" );
    1953                         $$ = $4->addType( $3 )->addQualifiers( $1 )->addTypedef();
     1953                        $$ = $4->addQualifiers( $1 )->addType( $3 )->addTypedef();
    19541954                }
    19551955        | type_specifier TYPEDEF declarator
     
    19611961                {
    19621962                        typedefTable.addToEnclosingScope( *$4->name, TYPEDEFname, "8" );
    1963                         $$ = $4->addQualifiers( $1 )->addTypedef()->addType( $1 );
     1963                        $$ = $4->addQualifiers( $1 )->addType( $1 )->addTypedef();
    19641964                }
    19651965        ;
     
    19831983        | typedef_expression                                                            // deprecated GCC, naming expression type
    19841984        | sue_declaration_specifier
     1985                {
     1986                        assert( $1->type );
     1987                        if ( $1->type->qualifiers.val != 0 ) {
     1988                                SemanticError( yylloc, "Useless type qualifier in empty declaration." ); $$ = nullptr;
     1989                        }
     1990                }
    19851991        ;
    19861992
  • src/Parser/parserutility.h

    r1180175 r640b3df  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // parserutility.h --
     7// parserutility.h -- Collected utilities for the parser.
    88//
    99// Author           : Rodolfo G. Esteves
    1010// Created On       : Sat May 16 15:31:46 2015
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sat Jul 22 09:32:58 2017
    13 // Update Count     : 4
     11// Last Modified By : Andrew Beach
     12// Last Modified On : Thr Feb 16 12:34:00 2023
     13// Update Count     : 5
    1414//
    1515
     
    2020Expression *notZeroExpr( Expression *orig );
    2121
     22template< typename T, typename U >
     23struct maybeBuild_t {
     24        static T * doit( const U *orig ) {
     25                if ( orig ) {
     26                        return orig->build();
     27                } else {
     28                        return 0;
     29                }
     30        }
     31};
     32
     33template< typename T, typename U >
     34static inline T * maybeBuild( const U *orig ) {
     35        return maybeBuild_t<T,U>::doit(orig);
     36}
     37
     38template< typename T, typename U >
     39static inline T * maybeMoveBuild( const U *orig ) {
     40        T* ret = maybeBuild<T>(orig);
     41        delete orig;
     42        return ret;
     43}
     44
    2245// Local Variables: //
    2346// tab-width: 4 //
  • src/ResolvExpr/CurrentObject.cc

    r1180175 r640b3df  
    2626#include "AST/Init.hpp"                // for Designation
    2727#include "AST/Node.hpp"                // for readonly
    28 #include "AST/Print.hpp"                // for readonly
     28#include "AST/Print.hpp"               // for readonly
    2929#include "AST/Type.hpp"
     30#include "Common/Eval.h"               // for eval
    3031#include "Common/Indenter.h"           // for Indenter, operator<<
    3132#include "Common/SemanticError.h"      // for SemanticError
  • src/ResolvExpr/ResolveAssertions.cc

    r1180175 r640b3df  
    3030#include "Common/FilterCombos.h"    // for filterCombos
    3131#include "Common/Indenter.h"        // for Indenter
    32 #include "Common/utility.h"         // for sort_mins
    3332#include "GenPoly/GenPoly.h"        // for getFunctionType
    3433#include "ResolvExpr/AlternativeFinder.h"  // for computeConversionCost
  • src/ResolvExpr/Resolver.cc

    r1180175 r640b3df  
    3838#include "AST/SymbolTable.hpp"
    3939#include "AST/Type.hpp"
     40#include "Common/Eval.h"                 // for eval
    4041#include "Common/PassVisitor.h"          // for PassVisitor
    4142#include "Common/SemanticError.h"        // for SemanticError
  • src/ResolvExpr/Resolver.h

    r1180175 r640b3df  
    3434        class Decl;
    3535        class DeletedExpr;
     36        class Expr;
    3637        class Init;
    3738        class StmtExpr;
  • src/SynTree/AggregateDecl.cc

    r1180175 r640b3df  
    1919
    2020#include "Attribute.h"           // for Attribute
     21#include "Common/Eval.h"         // for eval
    2122#include "Common/utility.h"      // for printAll, cloneAll, deleteAll
    2223#include "Declaration.h"         // for AggregateDecl, TypeDecl, Declaration
  • src/SynTree/Type.h

    r1180175 r640b3df  
    99// Author           : Richard C. Bilson
    1010// Created On       : Mon May 18 07:44:20 2015
    11 // Last Modified By : Andrew Beach
    12 // Last Modified On : Wed Jul 14 15:40:00 2021
    13 // Update Count     : 171
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Sun Feb 19 22:37:10 2023
     13// Update Count     : 176
    1414//
    1515
     
    2323
    2424#include "BaseSyntaxNode.h"  // for BaseSyntaxNode
    25 #include "Common/utility.h"  // for operator+
     25#include "Common/Iterate.hpp"// for operator+
     26#include "Common/utility.h"  // for toCString
    2627#include "Mutator.h"         // for Mutator
    2728#include "SynTree.h"         // for AST nodes
     
    124125                bool operator!=( Qualifiers other ) const { return (val & Mask) != (other.val & Mask); }
    125126                bool operator<=( Qualifiers other ) const {
    126                         return is_const    <= other.is_const        //Any non-const converts to const without cost
    127                                         && is_volatile <= other.is_volatile     //Any non-volatile converts to volatile without cost
    128                                         && is_mutex    >= other.is_mutex        //Any mutex converts to non-mutex without cost
    129                                         && is_atomic   == other.is_atomic;      //No conversion from atomic to non atomic is free
     127                        return is_const    <= other.is_const        // Any non-const converts to const without cost
     128                                && is_volatile <= other.is_volatile             // Any non-volatile converts to volatile without cost
     129                                && is_mutex    >= other.is_mutex                // Any mutex converts to non-mutex without cost
     130                                && is_atomic   == other.is_atomic;              // No conversion from atomic to non atomic is free
    130131                }
    131132                bool operator<( Qualifiers other ) const { return *this != other && *this <= other; }
     
    189190        virtual TypeSubstitution genericSubstitution() const;
    190191
    191         virtual Type *clone() const = 0;
     192        virtual Type * clone() const = 0;
    192193        virtual void accept( Visitor & v ) = 0;
    193194        virtual void accept( Visitor & v ) const = 0;
    194         virtual Type *acceptMutator( Mutator & m ) = 0;
     195        virtual Type * acceptMutator( Mutator & m ) = 0;
    195196        virtual void print( std::ostream & os, Indenter indent = {} ) const;
    196197};
     
    207208        virtual bool isComplete() const override { return false; }
    208209
    209         virtual VoidType *clone() const override { return new VoidType( *this ); }
    210         virtual void accept( Visitor & v ) override { v.visit( this ); }
    211         virtual void accept( Visitor & v ) const override { v.visit( this ); }
    212         virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); }
     210        virtual VoidType * clone() const override { return new VoidType( *this ); }
     211        virtual void accept( Visitor & v ) override { v.visit( this ); }
     212        virtual void accept( Visitor & v ) const override { v.visit( this ); }
     213        virtual Type * acceptMutator( Mutator & m ) override { return m.mutate( this ); }
    213214        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
    214215};
     
    259260        // GENERATED END
    260261
    261         static const char *typeNames[];                                         // string names for basic types, MUST MATCH with Kind
     262        static const char * typeNames[];                                        // string names for basic types, MUST MATCH with Kind
    262263
    263264        BasicType( const Type::Qualifiers & tq, Kind bt, const std::list< Attribute * > & attributes = std::list< Attribute * >() );
     
    266267        void set_kind( Kind newValue ) { kind = newValue; }
    267268
    268         virtual BasicType *clone() const override { return new BasicType( *this ); }
    269         virtual void accept( Visitor & v ) override { v.visit( this ); }
    270         virtual void accept( Visitor & v ) const override { v.visit( this ); }
    271         virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); }
     269        virtual BasicType * clone() const override { return new BasicType( *this ); }
     270        virtual void accept( Visitor & v ) override { v.visit( this ); }
     271        virtual void accept( Visitor & v ) const override { v.visit( this ); }
     272        virtual Type * acceptMutator( Mutator & m ) override { return m.mutate( this ); }
    272273        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
    273274        bool isInteger() const;
     
    279280
    280281        // In C99, pointer types can be qualified in many ways e.g., int f( int a[ static 3 ] )
    281         Expression *dimension;
     282        Expression * dimension;
    282283        bool isVarLen;
    283284        bool isStatic;
    284285
    285         PointerType( const Type::Qualifiers & tq, Type *base, const std::list< Attribute * > & attributes = std::list< Attribute * >() );
    286         PointerType( const Type::Qualifiers & tq, Type *base, Expression *dimension, bool isVarLen, bool isStatic, const std::list< Attribute * > & attributes = std::list< Attribute * >() );
     286        PointerType( const Type::Qualifiers & tq, Type * base, const std::list< Attribute * > & attributes = std::list< Attribute * >() );
     287        PointerType( const Type::Qualifiers & tq, Type * base, Expression * dimension, bool isVarLen, bool isStatic, const std::list< Attribute * > & attributes = std::list< Attribute * >() );
    287288        PointerType( const PointerType& );
    288289        virtual ~PointerType();
    289290
    290         Type *get_base() { return base; }
    291         void set_base( Type *newValue ) { base = newValue; }
    292         Expression *get_dimension() { return dimension; }
    293         void set_dimension( Expression *newValue ) { dimension = newValue; }
     291        Type * get_base() { return base; }
     292        void set_base( Type * newValue ) { base = newValue; }
     293        Expression * get_dimension() { return dimension; }
     294        void set_dimension( Expression * newValue ) { dimension = newValue; }
    294295        bool get_isVarLen() { return isVarLen; }
    295296        void set_isVarLen( bool newValue ) { isVarLen = newValue; }
     
    301302        virtual bool isComplete() const override { return ! isVarLen; }
    302303
    303         virtual PointerType *clone() const override { return new PointerType( *this ); }
    304         virtual void accept( Visitor & v ) override { v.visit( this ); }
    305         virtual void accept( Visitor & v ) const override { v.visit( this ); }
    306         virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); }
     304        virtual PointerType * clone() const override { return new PointerType( * this ); }
     305        virtual void accept( Visitor & v ) override { v.visit( this ); }
     306        virtual void accept( Visitor & v ) const override { v.visit( this ); }
     307        virtual Type * acceptMutator( Mutator & m ) override { return m.mutate( this ); }
    307308        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
    308309};
     
    310311class ArrayType : public Type {
    311312  public:
    312         Type *base;
    313         Expression *dimension;
     313        Type * base;
     314        Expression * dimension;
    314315        bool isVarLen;
    315316        bool isStatic;
    316317
    317         ArrayType( const Type::Qualifiers & tq, Type *base, Expression *dimension, bool isVarLen, bool isStatic, const std::list< Attribute * > & attributes = std::list< Attribute * >() );
     318        ArrayType( const Type::Qualifiers & tq, Type * base, Expression * dimension, bool isVarLen, bool isStatic, const std::list< Attribute * > & attributes = std::list< Attribute * >() );
    318319        ArrayType( const ArrayType& );
    319320        virtual ~ArrayType();
    320321
    321         Type *get_base() { return base; }
    322         void set_base( Type *newValue ) { base = newValue; }
    323         Expression *get_dimension() { return dimension; }
    324         void set_dimension( Expression *newValue ) { dimension = newValue; }
     322        Type * get_base() { return base; }
     323        void set_base( Type * newValue ) { base = newValue; }
     324        Expression * get_dimension() { return dimension; }
     325        void set_dimension( Expression * newValue ) { dimension = newValue; }
    325326        bool get_isVarLen() { return isVarLen; }
    326327        void set_isVarLen( bool newValue ) { isVarLen = newValue; }
     
    333334        virtual bool isComplete() const override { return dimension || isVarLen; }
    334335
    335         virtual ArrayType *clone() const override { return new ArrayType( *this ); }
    336         virtual void accept( Visitor & v ) override { v.visit( this ); }
    337         virtual void accept( Visitor & v ) const override { v.visit( this ); }
    338         virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); }
     336        virtual ArrayType * clone() const override { return new ArrayType( *this ); }
     337        virtual void accept( Visitor & v ) override { v.visit( this ); }
     338        virtual void accept( Visitor & v ) const override { v.visit( this ); }
     339        virtual Type * acceptMutator( Mutator & m ) override { return m.mutate( this ); }
    339340        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
    340341};
     
    348349        virtual ~QualifiedType();
    349350
    350         virtual QualifiedType *clone() const override { return new QualifiedType( *this ); }
    351         virtual void accept( Visitor & v ) override { v.visit( this ); }
    352         virtual void accept( Visitor & v ) const override { v.visit( this ); }
    353         virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); }
     351        virtual QualifiedType * clone() const override { return new QualifiedType( *this ); }
     352        virtual void accept( Visitor & v ) override { v.visit( this ); }
     353        virtual void accept( Visitor & v ) const override { v.visit( this ); }
     354        virtual Type * acceptMutator( Mutator & m ) override { return m.mutate( this ); }
    354355        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
    355356};
     
    357358class ReferenceType : public Type {
    358359public:
    359         Type *base;
    360 
    361         ReferenceType( const Type::Qualifiers & tq, Type *base, const std::list< Attribute * > & attributes = std::list< Attribute * >() );
     360        Type * base;
     361
     362        ReferenceType( const Type::Qualifiers & tq, Type * base, const std::list< Attribute * > & attributes = std::list< Attribute * >() );
    362363        ReferenceType( const ReferenceType & );
    363364        virtual ~ReferenceType();
    364365
    365         Type *get_base() { return base; }
    366         void set_base( Type *newValue ) { base = newValue; }
     366        Type * get_base() { return base; }
     367        void set_base( Type * newValue ) { base = newValue; }
    367368
    368369        virtual int referenceDepth() const override;
     
    375376        virtual TypeSubstitution genericSubstitution() const override;
    376377
    377         virtual ReferenceType *clone() const override { return new ReferenceType( *this ); }
    378         virtual void accept( Visitor & v ) override { v.visit( this ); }
    379         virtual void accept( Visitor & v ) const override { v.visit( this ); }
    380         virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); }
     378        virtual ReferenceType * clone() const override { return new ReferenceType( *this ); }
     379        virtual void accept( Visitor & v ) override { v.visit( this ); }
     380        virtual void accept( Visitor & v ) const override { v.visit( this ); }
     381        virtual Type * acceptMutator( Mutator & m ) override { return m.mutate( this ); }
    381382        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
    382383};
     
    405406        bool isUnprototyped() const { return isVarArgs && parameters.size() == 0; }
    406407
    407         virtual FunctionType *clone() const override { return new FunctionType( *this ); }
    408         virtual void accept( Visitor & v ) override { v.visit( this ); }
    409         virtual void accept( Visitor & v ) const override { v.visit( this ); }
    410         virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); }
     408        virtual FunctionType * clone() const override { return new FunctionType( *this ); }
     409        virtual void accept( Visitor & v ) override { v.visit( this ); }
     410        virtual void accept( Visitor & v ) const override { v.visit( this ); }
     411        virtual Type * acceptMutator( Mutator & m ) override { return m.mutate( this ); }
    411412        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
    412413};
     
    414415class ReferenceToType : public Type {
    415416  public:
    416         std::list< Expression* > parameters;
     417        std::list< Expression * > parameters;
    417418        std::string name;
    418419        bool hoistType;
     
    428429        void set_hoistType( bool newValue ) { hoistType = newValue; }
    429430
    430         virtual ReferenceToType *clone() const override = 0;
     431        virtual ReferenceToType * clone() const override = 0;
    431432        virtual void accept( Visitor & v ) override = 0;
    432         virtual Type *acceptMutator( Mutator & m ) override = 0;
     433        virtual Type * acceptMutator( Mutator & m ) override = 0;
    433434        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
    434435
     
    443444        // this decl is not "owned" by the struct inst; it is merely a pointer to elsewhere in the tree,
    444445        // where the structure used in this type is actually defined
    445         StructDecl *baseStruct;
     446        StructDecl * baseStruct;
    446447
    447448        StructInstType( const Type::Qualifiers & tq, const std::string & name, const std::list< Attribute * > & attributes = std::list< Attribute * >()  ) : Parent( tq, name, attributes ), baseStruct( 0 ) {}
     
    449450        StructInstType( const StructInstType & other ) : Parent( other ), baseStruct( other.baseStruct ) {}
    450451
    451         StructDecl *get_baseStruct() const { return baseStruct; }
    452         void set_baseStruct( StructDecl *newValue ) { baseStruct = newValue; }
     452        StructDecl * get_baseStruct() const { return baseStruct; }
     453        void set_baseStruct( StructDecl * newValue ) { baseStruct = newValue; }
    453454
    454455        /// Accesses generic parameters of base struct (NULL if none such)
     
    466467        void lookup( const std::string & name, std::list< Declaration* > & foundDecls ) const override;
    467468
    468         virtual StructInstType *clone() const override { return new StructInstType( *this ); }
    469         virtual void accept( Visitor & v ) override { v.visit( this ); }
    470         virtual void accept( Visitor & v ) const override { v.visit( this ); }
    471         virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); }
     469        virtual StructInstType * clone() const override { return new StructInstType( *this ); }
     470        virtual void accept( Visitor & v ) override { v.visit( this ); }
     471        virtual void accept( Visitor & v ) const override { v.visit( this ); }
     472        virtual Type * acceptMutator( Mutator & m ) override { return m.mutate( this ); }
    472473
    473474        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
     
    481482        // this decl is not "owned" by the union inst; it is merely a pointer to elsewhere in the tree,
    482483        // where the union used in this type is actually defined
    483         UnionDecl *baseUnion;
     484        UnionDecl * baseUnion;
    484485
    485486        UnionInstType( const Type::Qualifiers & tq, const std::string & name, const std::list< Attribute * > & attributes = std::list< Attribute * >()  ) : Parent( tq, name, attributes ), baseUnion( 0 ) {}
     
    487488        UnionInstType( const UnionInstType & other ) : Parent( other ), baseUnion( other.baseUnion ) {}
    488489
    489         UnionDecl *get_baseUnion() const { return baseUnion; }
     490        UnionDecl * get_baseUnion() const { return baseUnion; }
    490491        void set_baseUnion( UnionDecl * newValue ) { baseUnion = newValue; }
    491492
     
    504505        void lookup( const std::string & name, std::list< Declaration* > & foundDecls ) const override;
    505506
    506         virtual UnionInstType *clone() const override { return new UnionInstType( *this ); }
    507         virtual void accept( Visitor & v ) override { v.visit( this ); }
    508         virtual void accept( Visitor & v ) const override { v.visit( this ); }
    509         virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); }
     507        virtual UnionInstType * clone() const override { return new UnionInstType( *this ); }
     508        virtual void accept( Visitor & v ) override { v.visit( this ); }
     509        virtual void accept( Visitor & v ) const override { v.visit( this ); }
     510        virtual Type * acceptMutator( Mutator & m ) override { return m.mutate( this ); }
    510511
    511512        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
     
    519520        // this decl is not "owned" by the enum inst; it is merely a pointer to elsewhere in the tree,
    520521        // where the enum used in this type is actually defined
    521         EnumDecl *baseEnum = nullptr;
     522        EnumDecl * baseEnum = nullptr;
    522523
    523524        EnumInstType( const Type::Qualifiers & tq, const std::string & name, const std::list< Attribute * > & attributes = std::list< Attribute * >()  ) : Parent( tq, name, attributes ) {}
     
    525526        EnumInstType( const EnumInstType & other ) : Parent( other ), baseEnum( other.baseEnum ) {}
    526527
    527         EnumDecl *get_baseEnum() const { return baseEnum; }
    528         void set_baseEnum( EnumDecl *newValue ) { baseEnum = newValue; }
     528        EnumDecl * get_baseEnum() const { return baseEnum; }
     529        void set_baseEnum( EnumDecl * newValue ) { baseEnum = newValue; }
    529530
    530531        virtual bool isComplete() const override;
     
    532533        virtual AggregateDecl * getAggr() const override;
    533534
    534         virtual EnumInstType *clone() const override { return new EnumInstType( *this ); }
    535         virtual void accept( Visitor & v ) override { v.visit( this ); }
    536         virtual void accept( Visitor & v ) const override { v.visit( this ); }
    537         virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); }
     535        virtual EnumInstType * clone() const override { return new EnumInstType( *this ); }
     536        virtual void accept( Visitor & v ) override { v.visit( this ); }
     537        virtual void accept( Visitor & v ) const override { v.visit( this ); }
     538        virtual Type * acceptMutator( Mutator & m ) override { return m.mutate( this ); }
    538539
    539540        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
     
    556557        virtual bool isComplete() const override;
    557558
    558         virtual TraitInstType *clone() const override { return new TraitInstType( *this ); }
    559         virtual void accept( Visitor & v ) override { v.visit( this ); }
    560         virtual void accept( Visitor & v ) const override { v.visit( this ); }
    561         virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); }
     559        virtual TraitInstType * clone() const override { return new TraitInstType( *this ); }
     560        virtual void accept( Visitor & v ) override { v.visit( this ); }
     561        virtual void accept( Visitor & v ) const override { v.visit( this ); }
     562        virtual Type * acceptMutator( Mutator & m ) override { return m.mutate( this ); }
    562563  private:
    563564        virtual std::string typeString() const override;
     
    569570        // this decl is not "owned" by the type inst; it is merely a pointer to elsewhere in the tree,
    570571        // where the type used here is actually defined
    571         TypeDecl *baseType;
     572        TypeDecl * baseType;
    572573        bool isFtype;
    573574
    574         TypeInstType( const Type::Qualifiers & tq, const std::string & name, TypeDecl *baseType, const std::list< Attribute * > & attributes = std::list< Attribute * >()  );
     575        TypeInstType( const Type::Qualifiers & tq, const std::string & name, TypeDecl * baseType, const std::list< Attribute * > & attributes = std::list< Attribute * >()  );
    575576        TypeInstType( const Type::Qualifiers & tq, const std::string & name, bool isFtype, const std::list< Attribute * > & attributes = std::list< Attribute * >()  );
    576577        TypeInstType( const TypeInstType & other );
    577578        ~TypeInstType();
    578579
    579         TypeDecl *get_baseType() const { return baseType; }
    580         void set_baseType( TypeDecl *newValue );
     580        TypeDecl * get_baseType() const { return baseType; }
     581        void set_baseType( TypeDecl * newValue );
    581582        bool get_isFtype() const { return isFtype; }
    582583        void set_isFtype( bool newValue ) { isFtype = newValue; }
     
    584585        virtual bool isComplete() const override;
    585586
    586         virtual TypeInstType *clone() const override { return new TypeInstType( *this ); }
    587         virtual void accept( Visitor & v ) override { v.visit( this ); }
    588         virtual void accept( Visitor & v ) const override { v.visit( this ); }
    589         virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); }
     587        virtual TypeInstType * clone() const override { return new TypeInstType( *this ); }
     588        virtual void accept( Visitor & v ) override { v.visit( this ); }
     589        virtual void accept( Visitor & v ) const override { v.visit( this ); }
     590        virtual Type * acceptMutator( Mutator & m ) override { return m.mutate( this ); }
    590591        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
    591592  private:
     
    622623        // virtual bool isComplete() const override { return true; } // xxx - not sure if this is right, might need to recursively check complete-ness
    623624
    624         virtual TupleType *clone() const override { return new TupleType( *this ); }
    625         virtual void accept( Visitor & v ) override { v.visit( this ); }
    626         virtual void accept( Visitor & v ) const override { v.visit( this ); }
    627         virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); }
     625        virtual TupleType * clone() const override { return new TupleType( *this ); }
     626        virtual void accept( Visitor & v ) override { v.visit( this ); }
     627        virtual void accept( Visitor & v ) const override { v.visit( this ); }
     628        virtual Type * acceptMutator( Mutator & m ) override { return m.mutate( this ); }
    628629        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
    629630};
     
    631632class TypeofType : public Type {
    632633  public:
    633         Expression *expr;    ///< expression to take the type of
    634         bool is_basetypeof;  ///< true iff is basetypeof type
    635 
    636         TypeofType( const Type::Qualifiers & tq, Expression *expr, const std::list< Attribute * > & attributes = std::list< Attribute * >() );
    637         TypeofType( const Type::Qualifiers & tq, Expression *expr, bool is_basetypeof,
     634        Expression * expr;              ///< expression to take the type of
     635        bool is_basetypeof;             ///< true iff is basetypeof type
     636
     637        TypeofType( const Type::Qualifiers & tq, Expression * expr, const std::list< Attribute * > & attributes = std::list< Attribute * >() );
     638        TypeofType( const Type::Qualifiers & tq, Expression * expr, bool is_basetypeof,
    638639                const std::list< Attribute * > & attributes = std::list< Attribute * >() );
    639640        TypeofType( const TypeofType& );
    640641        virtual ~TypeofType();
    641642
    642         Expression *get_expr() const { return expr; }
    643         void set_expr( Expression *newValue ) { expr = newValue; }
     643        Expression * get_expr() const { return expr; }
     644        void set_expr( Expression * newValue ) { expr = newValue; }
    644645
    645646        virtual bool isComplete() const override { assert( false ); return false; }
    646647
    647         virtual TypeofType *clone() const override { return new TypeofType( *this ); }
    648         virtual void accept( Visitor & v ) override { v.visit( this ); }
    649         virtual void accept( Visitor & v ) const override { v.visit( this ); }
    650         virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); }
     648        virtual TypeofType * clone() const override { return new TypeofType( *this ); }
     649        virtual void accept( Visitor & v ) override { v.visit( this ); }
     650        virtual void accept( Visitor & v ) const override { v.visit( this ); }
     651        virtual Type * acceptMutator( Mutator & m ) override { return m.mutate( this ); }
    651652        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
    652653};
     
    654655class VTableType : public Type {
    655656public:
    656         Type *base;
    657 
    658         VTableType( const Type::Qualifiers & tq, Type *base,
     657        Type * base;
     658
     659        VTableType( const Type::Qualifiers & tq, Type * base,
    659660                const std::list< Attribute * > & attributes = std::list< Attribute * >() );
    660661        VTableType( const VTableType & );
    661662        virtual ~VTableType();
    662663
    663         Type *get_base() { return base; }
    664         void set_base( Type *newValue ) { base = newValue; }
    665 
    666         virtual VTableType *clone() const override { return new VTableType( *this ); }
    667         virtual void accept( Visitor & v ) override { v.visit( this ); }
    668         virtual void accept( Visitor & v ) const override { v.visit( this ); }
    669         virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); }
     664        Type * get_base() { return base; }
     665        void set_base( Type * newValue ) { base = newValue; }
     666
     667        virtual VTableType * clone() const override { return new VTableType( *this ); }
     668        virtual void accept( Visitor & v ) override { v.visit( this ); }
     669        virtual void accept( Visitor & v ) const override { v.visit( this ); }
     670        virtual Type * acceptMutator( Mutator & m ) override { return m.mutate( this ); }
    670671        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
    671672};
     
    674675  public:
    675676        std::string name;
    676         Expression *expr;
    677         Type *type;
     677        Expression * expr;
     678        Type * type;
    678679        bool isType;
    679680
    680         AttrType( const Type::Qualifiers & tq, const std::string & name, Expression *expr, const std::list< Attribute * > & attributes = std::list< Attribute * >() );
    681         AttrType( const Type::Qualifiers & tq, const std::string & name, Type *type, const std::list< Attribute * > & attributes = std::list< Attribute * >()  );
     681        AttrType( const Type::Qualifiers & tq, const std::string & name, Expression * expr, const std::list< Attribute * > & attributes = std::list< Attribute * >() );
     682        AttrType( const Type::Qualifiers & tq, const std::string & name, Type * type, const std::list< Attribute * > & attributes = std::list< Attribute * >()  );
    682683        AttrType( const AttrType& );
    683684        virtual ~AttrType();
     
    685686        const std::string & get_name() const { return name; }
    686687        void set_name( const std::string & newValue ) { name = newValue; }
    687         Expression *get_expr() const { return expr; }
    688         void set_expr( Expression *newValue ) { expr = newValue; }
    689         Type *get_type() const { return type; }
    690         void set_type( Type *newValue ) { type = newValue; }
     688        Expression * get_expr() const { return expr; }
     689        void set_expr( Expression * newValue ) { expr = newValue; }
     690        Type * get_type() const { return type; }
     691        void set_type( Type * newValue ) { type = newValue; }
    691692        bool get_isType() const { return isType; }
    692693        void set_isType( bool newValue ) { isType = newValue; }
     
    694695        virtual bool isComplete() const override { assert( false ); } // xxx - not sure what to do here
    695696
    696         virtual AttrType *clone() const override { return new AttrType( *this ); }
    697         virtual void accept( Visitor & v ) override { v.visit( this ); }
    698         virtual void accept( Visitor & v ) const override { v.visit( this ); }
    699         virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); }
     697        virtual AttrType * clone() const override { return new AttrType( *this ); }
     698        virtual void accept( Visitor & v ) override { v.visit( this ); }
     699        virtual void accept( Visitor & v ) const override { v.visit( this ); }
     700        virtual Type * acceptMutator( Mutator & m ) override { return m.mutate( this ); }
    700701        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
    701702};
     
    709710        virtual bool isComplete() const override{ return true; } // xxx - is this right?
    710711
    711         virtual VarArgsType *clone() const override { return new VarArgsType( *this ); }
    712         virtual void accept( Visitor & v ) override { v.visit( this ); }
    713         virtual void accept( Visitor & v ) const override { v.visit( this ); }
    714         virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); }
     712        virtual VarArgsType * clone() const override { return new VarArgsType( *this ); }
     713        virtual void accept( Visitor & v ) override { v.visit( this ); }
     714        virtual void accept( Visitor & v ) const override { v.visit( this ); }
     715        virtual Type * acceptMutator( Mutator & m ) override { return m.mutate( this ); }
    715716        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
    716717};
     
    722723        ZeroType( Type::Qualifiers tq, const std::list< Attribute * > & attributes = std::list< Attribute * >()  );
    723724
    724         virtual ZeroType *clone() const override { return new ZeroType( *this ); }
    725         virtual void accept( Visitor & v ) override { v.visit( this ); }
    726         virtual void accept( Visitor & v ) const override { v.visit( this ); }
    727         virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); }
     725        virtual ZeroType * clone() const override { return new ZeroType( *this ); }
     726        virtual void accept( Visitor & v ) override { v.visit( this ); }
     727        virtual void accept( Visitor & v ) const override { v.visit( this ); }
     728        virtual Type * acceptMutator( Mutator & m ) override { return m.mutate( this ); }
    728729        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
    729730};
     
    735736        OneType( Type::Qualifiers tq, const std::list< Attribute * > & attributes = std::list< Attribute * >()  );
    736737
    737         virtual OneType *clone() const override { return new OneType( *this ); }
    738         virtual void accept( Visitor & v ) override { v.visit( this ); }
    739         virtual void accept( Visitor & v ) const override { v.visit( this ); }
    740         virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); }
     738        virtual OneType * clone() const override { return new OneType( *this ); }
     739        virtual void accept( Visitor & v ) override { v.visit( this ); }
     740        virtual void accept( Visitor & v ) const override { v.visit( this ); }
     741        virtual Type * acceptMutator( Mutator & m ) override { return m.mutate( this ); }
    741742        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
    742743};
     
    746747        GlobalScopeType();
    747748
    748         virtual GlobalScopeType *clone() const override { return new GlobalScopeType( *this ); }
    749         virtual void accept( Visitor & v ) override { v.visit( this ); }
    750         virtual void accept( Visitor & v ) const override { v.visit( this ); }
    751         virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); }
     749        virtual GlobalScopeType * clone() const override { return new GlobalScopeType( *this ); }
     750        virtual void accept( Visitor & v ) override { v.visit( this ); }
     751        virtual void accept( Visitor & v ) const override { v.visit( this ); }
     752        virtual Type * acceptMutator( Mutator & m ) override { return m.mutate( this ); }
    752753        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
    753754};
  • src/Validate/HandleAttributes.cc

    r1180175 r640b3df  
    1717
    1818#include "CompilationState.h"
     19#include "Common/Eval.h"
    1920#include "Common/PassVisitor.h"
    2021#include "Common/SemanticError.h"
  • src/main.cc

    r1180175 r640b3df  
    1010// Created On       : Fri May 15 23:12:02 2015
    1111// Last Modified By : Andrew Beach
    12 // Last Modified On : Wed Oct  5 12:06:00 2022
    13 // Update Count     : 679
     12// Last Modified On : Thr Feb 16 10:08:00 2023
     13// Update Count     : 680
    1414//
    1515
     
    4040#include "CodeTools/TrackLoc.h"             // for fillLocations
    4141#include "Common/CodeLocationTools.hpp"     // for forceFillCodeLocations
    42 #include "Common/CompilerError.h"           // for CompilerError
    4342#include "Common/DeclStats.hpp"             // for printDeclStats
    4443#include "Common/ResolvProtoDump.hpp"       // for dumpAsResolverProto
    4544#include "Common/Stats.h"                   // for Stats
    46 #include "Common/UnimplementedError.h"      // for UnimplementedError
    4745#include "Common/utility.h"                 // for deleteAll, filter, printAll
    4846#include "Concurrency/Actors.hpp"           // for implementActors
     
    274272                        FILE * gcc_builtins = fopen( (PreludeDirector + "/gcc-builtins.cf").c_str(), "r" );
    275273                        assertf( gcc_builtins, "cannot open gcc-builtins.cf\n" );
    276                         parse( gcc_builtins, LinkageSpec::Compiler );
     274                        parse( gcc_builtins, ast::Linkage::Compiler );
    277275
    278276                        // read the extra prelude in, if not generating the cfa library
    279277                        FILE * extras = fopen( (PreludeDirector + "/extras.cf").c_str(), "r" );
    280278                        assertf( extras, "cannot open extras.cf\n" );
    281                         parse( extras, LinkageSpec::BuiltinC );
     279                        parse( extras, ast::Linkage::BuiltinC );
    282280
    283281                        if ( ! libcfap ) {
     
    285283                                FILE * prelude = fopen( (PreludeDirector + "/prelude.cfa").c_str(), "r" );
    286284                                assertf( prelude, "cannot open prelude.cfa\n" );
    287                                 parse( prelude, LinkageSpec::Intrinsic );
     285                                parse( prelude, ast::Linkage::Intrinsic );
    288286
    289287                                // Read to cfa builtins, if not generating the cfa library
    290288                                FILE * builtins = fopen( (PreludeDirector + "/builtins.cf").c_str(), "r" );
    291289                                assertf( builtins, "cannot open builtins.cf\n" );
    292                                 parse( builtins, LinkageSpec::BuiltinCFA );
    293                         } // if
    294                 } // if
    295 
    296                 parse( input, libcfap ? LinkageSpec::Intrinsic : LinkageSpec::Cforall, yydebug );
     290                                parse( builtins, ast::Linkage::BuiltinCFA );
     291                        } // if
     292                } // if
     293
     294                parse( input, libcfap ? ast::Linkage::Intrinsic : ast::Linkage::Cforall, yydebug );
    297295
    298296                transUnit = buildUnit();
     
    342340                PASS( "Generate Autogen Routines", Validate::autogenerateRoutines( transUnit ) );
    343341
    344         PASS( "Implement Actors", Concurrency::implementActors( transUnit ) );
    345 
     342                PASS( "Implement Actors", Concurrency::implementActors( transUnit ) );
    346343                PASS( "Implement Mutex", Concurrency::implementMutex( transUnit ) );
    347344                PASS( "Implement Thread Start", Concurrency::implementThreadStarter( transUnit ) );
     
    476473                } // if
    477474                e.print();
    478                 if ( output != &cout ) {
    479                         delete output;
    480                 } // if
    481                 return EXIT_FAILURE;
    482         } catch ( UnimplementedError & e ) {
    483                 cout << "Sorry, " << e.get_what() << " is not currently implemented" << endl;
    484                 if ( output != &cout ) {
    485                         delete output;
    486                 } // if
    487                 return EXIT_FAILURE;
    488         } catch ( CompilerError & e ) {
    489                 cerr << "Compiler Error: " << e.get_what() << endl;
    490                 cerr << "(please report bugs to [REDACTED])" << endl;
    491475                if ( output != &cout ) {
    492476                        delete output;
  • tests/include/includes.cfa

    r1180175 r640b3df  
    1010// Created On       : Wed May 27 17:56:53 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sun May 22 08:27:20 2022
    13 // Update Count     : 779
     12// Last Modified On : Mon Feb 20 21:51:04 2023
     13// Update Count     : 780
    1414//
    1515
     
    7272#include <gshadow.h>
    7373#include <iconv.h>
    74 #include <ifaddrs.h>
     74//#include <ifaddrs.h>                                                                  // causes warning messages that break the build
    7575#include <inttypes.h>
    7676#include <langinfo.h>
Note: See TracChangeset for help on using the changeset viewer.