├── .gitignore ├── cxx ├── external │ ├── CMakeLists.txt │ └── unittest │ │ ├── README.md │ │ ├── UnitTestMain │ │ ├── CMakeLists.txt │ │ └── TestMain.cpp │ │ ├── googlemock │ │ ├── include │ │ │ └── gmock │ │ │ │ ├── internal │ │ │ │ ├── custom │ │ │ │ │ ├── gmock-generated-actions.h │ │ │ │ │ ├── gmock-matchers.h │ │ │ │ │ └── gmock-port.h │ │ │ │ └── gmock-port.h │ │ │ │ ├── gmock-more-matchers.h │ │ │ │ ├── gmock.h │ │ │ │ └── gmock-cardinalities.h │ │ ├── README.LLVM │ │ ├── LICENSE.txt │ │ └── src │ │ │ ├── gmock-all.cc │ │ │ ├── gmock-cardinalities.cc │ │ │ ├── gmock-internal-utils.cc │ │ │ └── gmock.cc │ │ ├── googletest │ │ ├── README.LLVM │ │ ├── LICENSE.TXT │ │ ├── include │ │ │ └── gtest │ │ │ │ ├── internal │ │ │ │ ├── custom │ │ │ │ │ ├── gtest.h │ │ │ │ │ ├── gtest-printers.h │ │ │ │ │ ├── gtest-port.h │ │ │ │ │ └── raw-ostream.h │ │ │ │ ├── gtest-port-arch.h │ │ │ │ ├── gtest-string.h │ │ │ │ └── gtest-linked_ptr.h │ │ │ │ ├── gtest_prod.h │ │ │ │ ├── gtest-test-part.h │ │ │ │ └── gtest-message.h │ │ └── src │ │ │ ├── gtest-all.cc │ │ │ ├── gtest-typed-test.cc │ │ │ └── gtest-test-part.cc │ │ └── CMakeLists.txt ├── lib │ ├── CMakeLists.txt │ ├── AST │ │ ├── CMakeLists.txt │ │ ├── ASTContext.cpp │ │ ├── Number.cpp │ │ └── AST.cpp │ ├── Parser │ │ ├── CMakeLists.txt │ │ ├── genCharTab.py │ │ └── DatumParser.cpp │ └── Support │ │ ├── CMakeLists.txt │ │ ├── StringTable.cpp │ │ ├── UTF8.cpp │ │ └── CharacterProperties.cpp ├── unittests │ ├── Support │ │ ├── CMakeLists.txt │ │ └── SourceErrorManagerTest.cpp │ ├── Parser │ │ ├── CMakeLists.txt │ │ ├── DiagContext.h │ │ ├── DatumParserTest.cpp │ │ └── LexerTest.cpp │ └── CMakeLists.txt ├── CMakeLists.txt └── include │ └── s2020 │ ├── AST │ ├── NodeKinds.def │ ├── Characters.def │ ├── ASTContext.h │ ├── Number.h │ └── AST.h │ ├── Parser │ ├── TokenKinds.def │ ├── DatumParser.h │ └── Lexer.h │ └── Support │ ├── Warning.h │ ├── CharacterProperties.h │ ├── CodePointSet.h │ ├── StringTable.h │ └── UTF8.h ├── CMakeLists.txt ├── utils └── clang-format.sh ├── LICENSE ├── LICENSE-Hermes ├── log.md ├── .clang-format ├── cmake └── Lit.cmake └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | /cmake-build-* 2 | /build* 3 | /.idea 4 | -------------------------------------------------------------------------------- /cxx/external/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_subdirectory(unittest) 2 | -------------------------------------------------------------------------------- /cxx/external/unittest/README.md: -------------------------------------------------------------------------------- 1 | Copied from llvm/utils/unittest and tweaked to build here. 2 | -------------------------------------------------------------------------------- /cxx/lib/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_subdirectory(Support) 2 | add_subdirectory(AST) 3 | add_subdirectory(Parser) 4 | -------------------------------------------------------------------------------- /cxx/external/unittest/UnitTestMain/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_s2020_library(gtest_main 2 | TestMain.cpp 3 | LINK_LIBS gtest 4 | ) 5 | -------------------------------------------------------------------------------- /cxx/unittests/Support/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_s2020_unittest(S2020SupportTests 2 | SourceErrorManagerTest.cpp 3 | LINK_LIBS S2020Support 4 | ) 5 | 6 | -------------------------------------------------------------------------------- /cxx/lib/AST/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_s2020_library(S2020AST STATIC 2 | AST.cpp 3 | ASTContext.cpp 4 | Number.cpp 5 | LINK_LIBS S2020Support 6 | ) 7 | -------------------------------------------------------------------------------- /cxx/lib/Parser/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_s2020_library(S2020Parser STATIC 2 | DatumParser.cpp 3 | Lexer.cpp 4 | LINK_LIBS S2020AST S2020Support 5 | ) 6 | -------------------------------------------------------------------------------- /cxx/unittests/Parser/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_s2020_unittest(S2020LexerTests 2 | DatumParserTest.cpp 3 | LexerTest.cpp 4 | LINK_LIBS S2020Parser 5 | ) 6 | 7 | -------------------------------------------------------------------------------- /cxx/lib/Support/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_library(S2020Support STATIC 2 | CharacterProperties.cpp 3 | SourceErrorManager.cpp 4 | StringTable.cpp 5 | UTF8.cpp 6 | ) 7 | -------------------------------------------------------------------------------- /cxx/lib/AST/ASTContext.cpp: -------------------------------------------------------------------------------- 1 | #include "s2020/AST/ASTContext.h" 2 | 3 | namespace s2020 { 4 | namespace ast { 5 | 6 | ASTContext::ASTContext() = default; 7 | ASTContext::~ASTContext() = default; 8 | 9 | } // namespace ast 10 | } // namespace s2020 11 | -------------------------------------------------------------------------------- /cxx/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.15) 2 | project(Scheme2020) 3 | 4 | set(CMAKE_CXX_STANDARD 11) 5 | set(CMAKE_CXX_STANDARD_REQUIRED ON) 6 | set(CMAKE_CXX_EXTENSIONS OFF) 7 | 8 | 9 | include_directories(include) 10 | add_subdirectory(lib) 11 | add_subdirectory(external) 12 | add_subdirectory(unittests) 13 | -------------------------------------------------------------------------------- /cxx/include/s2020/AST/NodeKinds.def: -------------------------------------------------------------------------------- 1 | #ifndef S2020_AST_NODE 2 | #define S2020_AST_NODE(name) 3 | #endif 4 | 5 | // clang-format off 6 | 7 | S2020_AST_NODE(Boolean) 8 | S2020_AST_NODE(Number) 9 | S2020_AST_NODE(Character) 10 | S2020_AST_NODE(String) 11 | S2020_AST_NODE(Symbol) 12 | S2020_AST_NODE(Bytevector) 13 | S2020_AST_NODE(Pair) 14 | S2020_AST_NODE(Null) 15 | S2020_AST_NODE(Vector) 16 | 17 | #undef S2020_AST_NODE 18 | -------------------------------------------------------------------------------- /cxx/external/unittest/googlemock/include/gmock/internal/custom/gmock-generated-actions.h: -------------------------------------------------------------------------------- 1 | // This file was GENERATED by command: 2 | // pump.py gmock-generated-actions.h.pump 3 | // DO NOT EDIT BY HAND!!! 4 | 5 | #ifndef GMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_GENERATED_ACTIONS_H_ 6 | #define GMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_GENERATED_ACTIONS_H_ 7 | 8 | #endif // GMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_GENERATED_ACTIONS_H_ 9 | -------------------------------------------------------------------------------- /cxx/include/s2020/AST/Characters.def: -------------------------------------------------------------------------------- 1 | #ifndef S2020_CHARACTER 2 | #define S2020_CHARACTER(name, code) 3 | #endif 4 | 5 | // Named Scheme characters. 6 | 7 | S2020_CHARACTER(alarm, 0x07) 8 | S2020_CHARACTER(backspace, 0x08) 9 | S2020_CHARACTER(delete, 0x7f) 10 | S2020_CHARACTER(escape, 0x1b) 11 | S2020_CHARACTER(newline, 0x0a) 12 | S2020_CHARACTER(null, 0x00) 13 | S2020_CHARACTER(return, 0x0d) 14 | S2020_CHARACTER(space, 0x20) 15 | S2020_CHARACTER(tab, 0x09) 16 | 17 | #undef S2020_CHARACTER -------------------------------------------------------------------------------- /cxx/lib/Support/StringTable.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Facebook, Inc. and its affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #include "s2020/Support/StringTable.h" 9 | #include "llvm/Support/raw_ostream.h" 10 | 11 | namespace s2020 { 12 | 13 | llvm::raw_ostream &operator<<(llvm::raw_ostream &os, Identifier id) { 14 | return os << id.str(); 15 | } 16 | 17 | } // namespace s2020 18 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.15) 2 | project(Scheme2020) 3 | 4 | include(CMakePrintHelpers) 5 | 6 | # This needs LLVM_ROOT to be set. 7 | find_package(LLVM REQUIRED CONFIG) 8 | 9 | message(STATUS "Found LLVM ${LLVM_PACKAGE_VERSION}") 10 | message(STATUS "Using LLVMConfig.cmake in: ${LLVM_DIR}") 11 | 12 | include_directories(${LLVM_INCLUDE_DIRS}) 13 | add_definitions(${LLVM_DEFINITIONS}) 14 | 15 | list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/") 16 | include(S2020) 17 | include(Lit) 18 | 19 | add_subdirectory(cxx) 20 | -------------------------------------------------------------------------------- /cxx/include/s2020/Parser/TokenKinds.def: -------------------------------------------------------------------------------- 1 | #ifndef TOK 2 | #define TOK(name, str) 3 | #endif 4 | 5 | // clang-format off 6 | 7 | TOK(none, "") 8 | TOK(identifier, "") 9 | TOK(apostrophe, "'") 10 | TOK(backtick, "`") 11 | TOK(comma, ",") 12 | TOK(comma_at, ",@") 13 | TOK(period, ".") 14 | TOK(l_brace, "{") 15 | TOK(r_brace, "}") 16 | TOK(l_paren, "(") 17 | TOK(r_paren, ")") 18 | TOK(l_square, "[") 19 | TOK(r_square, "]") 20 | 21 | TOK(datum_comment, "#;") 22 | 23 | TOK(number, "") 24 | 25 | TOK(eof, "") 26 | 27 | #undef TOK 28 | -------------------------------------------------------------------------------- /cxx/lib/AST/Number.cpp: -------------------------------------------------------------------------------- 1 | #include "s2020/AST/Number.h" 2 | 3 | #include "llvm/Support/Format.h" 4 | #include "llvm/Support/raw_ostream.h" 5 | 6 | namespace s2020 { 7 | namespace ast { 8 | 9 | llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const Number &number) { 10 | switch (number.getKind()) { 11 | case NumberKind::exact: 12 | OS << number.getExact(); 13 | return OS; 14 | case NumberKind::inexact: 15 | OS << number.getInexact(); 16 | return OS; 17 | } 18 | assert(false && "unsupported Number kind"); 19 | return OS; 20 | } 21 | 22 | } // namespace ast 23 | } // namespace s2020 -------------------------------------------------------------------------------- /cxx/include/s2020/Parser/DatumParser.h: -------------------------------------------------------------------------------- 1 | #ifndef SCHEME2020_PARSER_DATUMPARSER_H 2 | #define SCHEME2020_PARSER_DATUMPARSER_H 3 | 4 | #include "s2020/AST/AST.h" 5 | 6 | #include "llvm/ADT/Optional.h" 7 | 8 | #include 9 | 10 | namespace s2020 { 11 | namespace parser { 12 | 13 | /// The specified input is parsed into a sequence of datums, until an error is 14 | /// encountered or EOF is reached. 15 | llvm::Optional> parseDatums( 16 | ast::ASTContext &context, 17 | const llvm::MemoryBuffer &input); 18 | 19 | } // namespace parser 20 | } // namespace s2020 21 | 22 | #endif // SCHEME2020_PARSER_DATUMPARSER_H 23 | -------------------------------------------------------------------------------- /cxx/external/unittest/googlemock/README.LLVM: -------------------------------------------------------------------------------- 1 | LLVM notes 2 | ---------- 3 | 4 | This directory contains the 'googlemock' component of Google Test 1.8.0, with 5 | all elements removed except for the actual source code, to minimize the 6 | addition to the LLVM distribution. 7 | 8 | Cleaned up as follows: 9 | 10 | # Remove all the unnecessary files and directories 11 | $ rm -f CMakeLists.txt configure* Makefile* CHANGES CONTRIBUTORS README README.md .gitignore 12 | $ rm -rf build-aux make msvc scripts test docs 13 | $ rm -f `find . -name \*\.pump` 14 | $ rm -f src/gmock_main.cc 15 | 16 | # Put the license in the consistent place for LLVM. 17 | $ mv LICENSE LICENSE.TXT 18 | -------------------------------------------------------------------------------- /cxx/external/unittest/googletest/README.LLVM: -------------------------------------------------------------------------------- 1 | LLVM notes 2 | ---------- 3 | 4 | This directory contains Google Test 1.8.0, with all elements removed except for 5 | the actual source code, to minimize the addition to the LLVM distribution. 6 | 7 | Cleaned up as follows: 8 | 9 | # Remove all the unnecessary files and directories 10 | $ rm -f CMakeLists.txt configure* Makefile* CHANGES CONTRIBUTORS README README.md .gitignore 11 | $ rm -rf build-aux cmake codegear m4 make msvc samples scripts test xcode docs 12 | $ rm -f `find . -name \*\.pump` 13 | $ rm -f src/gtest_main.cc 14 | 15 | # Put the license in the consistent place for LLVM. 16 | $ mv LICENSE LICENSE.TXT 17 | 18 | Modified as follows: 19 | * Added support for NetBSD, Minix and Haiku. 20 | * Added raw_os_ostream support to include/gtest/internal/custom/gtest-printers.h. 21 | -------------------------------------------------------------------------------- /cxx/unittests/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_custom_target(S2020UnitTests) 2 | set_target_properties(S2020UnitTests PROPERTIES FOLDER "Tests") 3 | 4 | function(add_s2020_unittest test_dirname) 5 | add_unittest(S2020UnitTests ${test_dirname} ${ARGN}) 6 | target_compile_definitions(${test_dirname} PUBLIC UNIT_TEST) 7 | endfunction() 8 | 9 | if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang" OR 10 | "${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU") 11 | # without this, because we build -Wextra, gtest warns when comparing 12 | # against integer constants 13 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-sign-compare") 14 | elseif ("${CMAKE_CXX_COMPILER_ID}" MATCHES "MSVC") 15 | # use of std::tr1 namespace (in GTest headers) 16 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -D_SILENCE_TR1_NAMESPACE_DEPRECATION_WARNING") 17 | endif() 18 | 19 | add_subdirectory(Support) 20 | add_subdirectory(Parser) 21 | -------------------------------------------------------------------------------- /utils/clang-format.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | IFS=$'\n' 3 | set -f 4 | 5 | FORMAT_ALL="" 6 | if [ "$1" == "-a" ]; then 7 | shift 8 | FORMAT_ALL="1" 9 | fi 10 | 11 | [ -n "$1" ] && echo "$0: Too many arguments" && exit 1 12 | 13 | FILES=() 14 | 15 | if [ -n "$FORMAT_ALL" ]; then 16 | echo "Formatting everything" 17 | FILES=( $(find . -path ./cxx/external -prune -o -path ./\*build\* -prune -o \ 18 | -name \*.h -print -o -name \*.cpp -print) ) 19 | elif ! git diff --exit-code --quiet ; then 20 | echo "Formatting only changed" 21 | FILES=( $(git diff --name-only -- '*.cpp' '*.h' '*.hpp') ) 22 | 23 | elif ! git log --exit-code "HEAD~1..HEAD" --author=$USER > /dev/null ; then 24 | read -r -p "Format files in last commit? [y/N]" reply 25 | if [[ $reply == [Yy] ]]; then 26 | FILES=( $(git diff --name-only "HEAD~1..HEAD" -- '*.cpp' '*.h' '*.hpp') ) 27 | else 28 | exit 1 29 | fi 30 | else 31 | echo "Nothing to format" 32 | exit 1 33 | fi 34 | 35 | for f in "${FILES[@]}"; do 36 | echo "$f" 37 | clang-format -i -style=file "$f" 38 | done 39 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Tzvetan Mikov 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /LICENSE-Hermes: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) Facebook, Inc. and its affiliates. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /cxx/include/s2020/AST/ASTContext.h: -------------------------------------------------------------------------------- 1 | #ifndef SCHEME2020_AST_ASTCONTEXT_H 2 | #define SCHEME2020_AST_ASTCONTEXT_H 3 | 4 | #include "s2020/AST/Number.h" 5 | #include "s2020/Support/SourceErrorManager.h" 6 | #include "s2020/Support/StringTable.h" 7 | 8 | #include "llvm/Support/Allocator.h" 9 | 10 | namespace s2020 { 11 | namespace ast { 12 | 13 | using Allocator = llvm::BumpPtrAllocator; 14 | 15 | class ASTContext { 16 | public: 17 | SourceErrorManager sm; 18 | Allocator allocator; 19 | StringTable stringTable{allocator}; 20 | 21 | ASTContext(); 22 | ~ASTContext(); 23 | 24 | Number makeExactNumber(ExactNumberT exact) { 25 | return Number{exact}; 26 | } 27 | Number makeInexactNumber(InexactNumberT inexact) { 28 | return Number{inexact}; 29 | } 30 | 31 | /// Allocates AST nodes. Should not be used for non-AST data because 32 | /// the memory may be freed during parsing. 33 | template 34 | T *allocateNode(size_t num = 1) { 35 | return allocator.template Allocate(num); 36 | } 37 | void *allocateNode(size_t size, size_t alignment) { 38 | return allocator.Allocate(size, alignment); 39 | } 40 | }; 41 | 42 | } // namespace ast 43 | } // namespace s2020 44 | 45 | #endif // SCHEME2020_AST_ASTCONTEXT_H 46 | -------------------------------------------------------------------------------- /log.md: -------------------------------------------------------------------------------- 1 | ### Feb 22, 2020 2 | - 10:44 PM: [initial Twitter announcement](https://twitter.com/tmikov/status/1231469792399220736). 3 | 4 | ### March 1st, 2020 5 | - 5:30 pm to 7:10 pm : 100 min 6 | - download and build LLVM 7 | - register domain name 8 | - review code from previous projects to reuse 9 | - Github project 10 | - README.md 11 | 12 | ### March 2nd, 2020 13 | - 9:30 pm to 9:50pm : 20 min 14 | - 10:00 pm to 11:00pm : 60 min 15 | - unit test infra 16 | - SourceErrorManager 17 | 18 | ### March 3rd, 2020 19 | - 6:30 pm to 7:45 pm: 75 min 20 | - Better LLVM integration 21 | - clang-format 22 | 23 | ### March 4th, 2020 24 | - 23:00 to 23:40 : 40 min 25 | 26 | ### March 5th, 2020 27 | - 17:15 to 19:55 : 160 min 28 | 29 | ### March 7th, 2020 30 | - 16:00 to 16:30 : 30 min 31 | - 19:30 to 21:30 : 120 min (total 605 min) 32 | - Partial lexer and lexer unittests 33 | 34 | ### March 8th, 2020 35 | - 17:00 to 19:30 : 150 min (total 755 min) 36 | - Add AST abstractions 37 | 38 | ### March 9th, 2020 39 | - 19:00 to 21:45 : 165 min (total 920 min) 40 | - Datum parser 41 | 42 | ### March 10th, 2020 43 | - 19:30 to 21:00 : 90 min (total 1010 min) 44 | - AST improvements 45 | - Datum parser and unittests 46 | -------------------------------------------------------------------------------- /cxx/external/unittest/googlemock/LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright 2008, Google Inc. 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are 6 | met: 7 | 8 | * Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | * Redistributions in binary form must reproduce the above 11 | copyright notice, this list of conditions and the following disclaimer 12 | in the documentation and/or other materials provided with the 13 | distribution. 14 | * Neither the name of Google Inc. nor the names of its 15 | contributors may be used to endorse or promote products derived from 16 | this software without specific prior written permission. 17 | 18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | -------------------------------------------------------------------------------- /cxx/external/unittest/googletest/LICENSE.TXT: -------------------------------------------------------------------------------- 1 | Copyright 2008, Google Inc. 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are 6 | met: 7 | 8 | * Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | * Redistributions in binary form must reproduce the above 11 | copyright notice, this list of conditions and the following disclaimer 12 | in the documentation and/or other materials provided with the 13 | distribution. 14 | * Neither the name of Google Inc. nor the names of its 15 | contributors may be used to endorse or promote products derived from 16 | this software without specific prior written permission. 17 | 18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | -------------------------------------------------------------------------------- /cxx/include/s2020/Support/Warning.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Facebook, Inc. and its affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #ifndef S2020_SUPPORT_WARNINGS_H 9 | #define S2020_SUPPORT_WARNINGS_H 10 | 11 | #include "llvm/ADT/DenseMapInfo.h" 12 | 13 | #include 14 | 15 | namespace s2020 { 16 | 17 | /// Categories of warnings the compiler might emit, that can be turned on or 18 | /// off. 19 | enum class Warning { 20 | NoWarning, 21 | UndefinedVariable, 22 | DirectEval, 23 | Misc, 24 | 25 | _NumWarnings, 26 | }; 27 | 28 | } // namespace s2020 29 | 30 | namespace llvm { 31 | 32 | using s2020::Warning; 33 | 34 | /// Information to store a \p Warning as the key of a \p DenseMap or \p 35 | /// DensetSet 36 | template <> 37 | struct DenseMapInfo { 38 | using Underlying = std::underlying_type::type; 39 | using UnderlyingInfo = DenseMapInfo; 40 | 41 | static inline Warning getEmptyKey() { 42 | return static_cast(UnderlyingInfo::getEmptyKey()); 43 | } 44 | 45 | static inline Warning getTombstoneKey() { 46 | return static_cast(UnderlyingInfo::getTombstoneKey()); 47 | } 48 | 49 | static unsigned getHashValue(Warning warning) { 50 | return UnderlyingInfo::getHashValue(static_cast(warning)); 51 | } 52 | 53 | static bool isEqual(Warning lhs, Warning rhs) { 54 | return lhs == rhs; 55 | } 56 | }; 57 | 58 | } // namespace llvm 59 | 60 | #endif // S2020_SUPPORT_SOURCEERRORMANAGER_H 61 | -------------------------------------------------------------------------------- /cxx/unittests/Parser/DiagContext.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Facebook, Inc. and its affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #ifndef S2020_TEST_PARSER_DIAGCONTEXT_H 9 | #define S2020_TEST_PARSER_DIAGCONTEXT_H 10 | 11 | #include "s2020/Parser/Lexer.h" 12 | 13 | namespace s2020 { 14 | namespace parser { 15 | 16 | class DiagContext { 17 | int errCount_{0}; 18 | int warnCount_{0}; 19 | std::string message_{}; 20 | 21 | public: 22 | explicit DiagContext(SourceErrorManager &mgr) { 23 | mgr.setDiagHandler(handler, this); 24 | } 25 | 26 | void clear() { 27 | errCount_ = warnCount_ = 0; 28 | } 29 | int getErrCount() const { 30 | return errCount_; 31 | } 32 | int getWarnCount() const { 33 | return warnCount_; 34 | } 35 | 36 | int getErrCountClear() { 37 | unsigned res = errCount_; 38 | clear(); 39 | return res; 40 | } 41 | int getWarnCountClear() { 42 | unsigned res = warnCount_; 43 | clear(); 44 | return res; 45 | } 46 | 47 | const std::string &getMessage() { 48 | return message_; 49 | } 50 | 51 | private: 52 | static void handler(const llvm::SMDiagnostic &msg, void *ctx) { 53 | DiagContext *diag = static_cast(ctx); 54 | if (msg.getKind() == llvm::SourceMgr::DK_Error) { 55 | ++diag->errCount_; 56 | diag->message_ = msg.getMessage(); 57 | } else if (msg.getKind() == llvm::SourceMgr::DK_Warning) { 58 | ++diag->warnCount_; 59 | diag->message_ = msg.getMessage(); 60 | } else { 61 | diag->message_.clear(); 62 | } 63 | } 64 | }; 65 | 66 | } // namespace parser 67 | } // namespace s2020 68 | 69 | #endif // S2020_TEST_PARSER_DIAGCONTEXT_H 70 | -------------------------------------------------------------------------------- /cxx/external/unittest/UnitTestMain/TestMain.cpp: -------------------------------------------------------------------------------- 1 | //===--- utils/unittest/UnitTestMain/TestMain.cpp - unittest driver -------===// 2 | // 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 | // See https://llvm.org/LICENSE.txt for license information. 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 | // 7 | //===----------------------------------------------------------------------===// 8 | 9 | #include "llvm/Support/CommandLine.h" 10 | #include "llvm/Support/Signals.h" 11 | #include "gmock/gmock.h" 12 | #include "gtest/gtest.h" 13 | 14 | #if defined(_WIN32) 15 | # include 16 | # if defined(_MSC_VER) 17 | # include 18 | # endif 19 | #endif 20 | 21 | const char *TestMainArgv0; 22 | 23 | int main(int argc, char **argv) { 24 | llvm::sys::PrintStackTraceOnErrorSignal(argv[0], 25 | true /* Disable crash reporting */); 26 | 27 | // Initialize both gmock and gtest. 28 | testing::InitGoogleMock(&argc, argv); 29 | 30 | llvm::cl::ParseCommandLineOptions(argc, argv); 31 | 32 | // Make it easy for a test to re-execute itself by saving argv[0]. 33 | TestMainArgv0 = argv[0]; 34 | 35 | # if defined(_WIN32) 36 | // Disable all of the possible ways Windows conspires to make automated 37 | // testing impossible. 38 | ::SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX); 39 | # if defined(_MSC_VER) 40 | ::_set_error_mode(_OUT_TO_STDERR); 41 | _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE | _CRTDBG_MODE_DEBUG); 42 | _CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDERR); 43 | _CrtSetReportMode(_CRT_ERROR, _CRTDBG_MODE_FILE | _CRTDBG_MODE_DEBUG); 44 | _CrtSetReportFile(_CRT_ERROR, _CRTDBG_FILE_STDERR); 45 | _CrtSetReportMode(_CRT_ASSERT, _CRTDBG_MODE_FILE | _CRTDBG_MODE_DEBUG); 46 | _CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR); 47 | # endif 48 | # endif 49 | 50 | return RUN_ALL_TESTS(); 51 | } 52 | -------------------------------------------------------------------------------- /cxx/unittests/Support/SourceErrorManagerTest.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Facebook, Inc. and its affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #include "s2020/Support/SourceErrorManager.h" 9 | 10 | #include "gtest/gtest.h" 11 | 12 | using namespace s2020; 13 | 14 | namespace { 15 | 16 | TEST(SourceErrorManagerTest, testFindSMLocFromCoords) { 17 | SourceErrorManager mgr{}; 18 | auto buf = 19 | llvm::MemoryBuffer::getMemBuffer("01\n34567\n\n\n\n", "TEST", false); 20 | auto *start = buf->getBufferStart(); 21 | auto *end = buf->getBufferEnd(); 22 | 23 | mgr.addNewSourceBuffer(std::move(buf)); 24 | 25 | // Test just a normal position first. 26 | SourceErrorManager::SourceCoords coords; 27 | auto loc1 = SMLoc::getFromPointer(start + 5); 28 | mgr.findBufferLineAndLoc(loc1, coords); 29 | ASSERT_TRUE(coords.isValid()); 30 | ASSERT_EQ(2, coords.line); 31 | ASSERT_EQ(3, coords.col); 32 | 33 | auto loc2 = mgr.findSMLocFromCoords(coords); 34 | ASSERT_EQ(loc1, loc2); 35 | 36 | // Test column 1 in an empty line. 37 | loc1 = SMLoc::getFromPointer(start + 10); 38 | mgr.findBufferLineAndLoc(loc1, coords); 39 | ASSERT_TRUE(coords.isValid()); 40 | ASSERT_EQ(4, coords.line); 41 | ASSERT_EQ(1, coords.col); 42 | 43 | loc2 = mgr.findSMLocFromCoords(coords); 44 | ASSERT_EQ(loc1, loc2); 45 | 46 | // Make it the last line. 47 | loc1 = SMLoc::getFromPointer(start + 11); 48 | mgr.findBufferLineAndLoc(loc1, coords); 49 | ASSERT_TRUE(coords.isValid()); 50 | ASSERT_EQ(5, coords.line); 51 | ASSERT_EQ(1, coords.col); 52 | 53 | loc2 = mgr.findSMLocFromCoords(coords); 54 | ASSERT_EQ(loc1, loc2); 55 | 56 | // Some errors show unexpected EOF at one past the last character. 57 | loc1 = SMLoc::getFromPointer(end); 58 | mgr.findBufferLineAndLoc(loc1, coords); 59 | ASSERT_TRUE(coords.isValid()); 60 | ASSERT_EQ(6, coords.line); 61 | ASSERT_EQ(1, coords.col); 62 | 63 | loc2 = mgr.findSMLocFromCoords(coords); 64 | ASSERT_EQ(loc1, loc2); 65 | } 66 | 67 | } // end anonymous namespace 68 | -------------------------------------------------------------------------------- /cxx/external/unittest/googletest/include/gtest/internal/custom/gtest.h: -------------------------------------------------------------------------------- 1 | // Copyright 2015, Google Inc. 2 | // All rights reserved. 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are 6 | // met: 7 | // 8 | // * Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above 11 | // copyright notice, this list of conditions and the following disclaimer 12 | // in the documentation and/or other materials provided with the 13 | // distribution. 14 | // * Neither the name of Google Inc. nor the names of its 15 | // contributors may be used to endorse or promote products derived from 16 | // this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | // 30 | // Injection point for custom user configurations. 31 | // The following macros can be defined: 32 | // 33 | // GTEST_OS_STACK_TRACE_GETTER_ - The name of an implementation of 34 | // OsStackTraceGetterInterface. 35 | // 36 | // ** Custom implementation starts here ** 37 | 38 | #ifndef GTEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_H_ 39 | #define GTEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_H_ 40 | 41 | #endif // GTEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_H_ 42 | -------------------------------------------------------------------------------- /cxx/external/unittest/googlemock/include/gmock/internal/custom/gmock-matchers.h: -------------------------------------------------------------------------------- 1 | // Copyright 2015, Google Inc. 2 | // All rights reserved. 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are 6 | // met: 7 | // 8 | // * Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above 11 | // copyright notice, this list of conditions and the following disclaimer 12 | // in the documentation and/or other materials provided with the 13 | // distribution. 14 | // * Neither the name of Google Inc. nor the names of its 15 | // contributors may be used to endorse or promote products derived from 16 | // this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | // 30 | // ============================================================ 31 | // An installation-specific extension point for gmock-matchers.h. 32 | // ============================================================ 33 | // 34 | // Adds google3 callback support to CallableTraits. 35 | // 36 | #ifndef GMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_CALLBACK_MATCHERS_H_ 37 | #define GMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_CALLBACK_MATCHERS_H_ 38 | 39 | #endif // GMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_CALLBACK_MATCHERS_H_ 40 | -------------------------------------------------------------------------------- /cxx/external/unittest/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | ######################################################################## 2 | # Experimental CMake build script for Google Test. 3 | # 4 | # Consider this a prototype. It will change drastically. For now, 5 | # this is only for people on the cutting edge. 6 | # 7 | # To run the tests for Google Test itself on Linux, use 'make test' or 8 | # ctest. You can select which tests to run using 'ctest -R regex'. 9 | # For more options, run 'ctest --help'. 10 | ######################################################################## 11 | # 12 | # Project-wide settings 13 | set(CMAKE_CXX_STANDARD 11) 14 | set(CMAKE_CXX_STANDARD_REQUIRED ON) 15 | set(CMAKE_CXX_EXTENSIONS OFF) 16 | 17 | 18 | # Where gtest's .h files can be found. 19 | include_directories( 20 | googletest/include 21 | googletest 22 | googlemock/include 23 | googlemock 24 | ) 25 | 26 | # LLVM requires C++11 but gtest doesn't correctly detect the availability 27 | # of C++11 on MSVC, so we force it on. 28 | add_definitions(-DGTEST_LANG_CXX11=1) 29 | add_definitions(-DGTEST_HAS_TR1_TUPLE=0) 30 | 31 | if(WIN32) 32 | add_definitions(-DGTEST_OS_WINDOWS=1) 33 | endif() 34 | 35 | # Google Test requires headers which need _ALL_SOURCE to build on AIX 36 | if (UNIX AND ${CMAKE_SYSTEM_NAME} MATCHES "AIX") 37 | remove_definitions("-D_XOPEN_SOURCE=700") 38 | add_definitions("-D_ALL_SOURCE") 39 | endif() 40 | 41 | if(SUPPORTS_VARIADIC_MACROS_FLAG) 42 | add_definitions("-Wno-variadic-macros") 43 | endif() 44 | if(SUPPORTS_GNU_ZERO_VARIADIC_MACRO_ARGUMENTS_FLAG) 45 | add_definitions("-Wno-gnu-zero-variadic-macro-arguments") 46 | endif() 47 | if(CXX_SUPPORTS_COVERED_SWITCH_DEFAULT_FLAG) 48 | add_definitions("-Wno-covered-switch-default") 49 | endif() 50 | 51 | #set(LLVM_REQUIRES_RTTI 1) 52 | add_definitions( -DGTEST_HAS_RTTI=0 ) 53 | 54 | #if (NOT LLVM_ENABLE_THREADS) 55 | # add_definitions( -DGTEST_HAS_PTHREAD=0 ) 56 | #endif() 57 | 58 | find_library(LLVM_PTHREAD_LIBRARY_PATH pthread) 59 | if (LLVM_PTHREAD_LIBRARY_PATH) 60 | list(APPEND LIBS pthread) 61 | endif() 62 | 63 | add_s2020_library(gtest 64 | googletest/src/gtest-all.cc 65 | googlemock/src/gmock-all.cc 66 | 67 | LLVM_COMPONENTS Support 68 | ) 69 | 70 | add_subdirectory(UnitTestMain) 71 | -------------------------------------------------------------------------------- /cxx/external/unittest/googletest/include/gtest/internal/custom/gtest-printers.h: -------------------------------------------------------------------------------- 1 | // Copyright 2015, Google Inc. 2 | // All rights reserved. 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are 6 | // met: 7 | // 8 | // * Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above 11 | // copyright notice, this list of conditions and the following disclaimer 12 | // in the documentation and/or other materials provided with the 13 | // distribution. 14 | // * Neither the name of Google Inc. nor the names of its 15 | // contributors may be used to endorse or promote products derived from 16 | // this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | // 30 | // This file provides an injection point for custom printers in a local 31 | // installation of gTest. 32 | // It will be included from gtest-printers.h and the overrides in this file 33 | // will be visible to everyone. 34 | // See documentation at gtest/gtest-printers.h for details on how to define a 35 | // custom printer. 36 | // 37 | // ** Custom implementation starts here ** 38 | 39 | #ifndef GTEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_PRINTERS_H_ 40 | #define GTEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_PRINTERS_H_ 41 | 42 | #endif // GTEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_PRINTERS_H_ 43 | -------------------------------------------------------------------------------- /cxx/external/unittest/googlemock/src/gmock-all.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2008, Google Inc. 2 | // All rights reserved. 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are 6 | // met: 7 | // 8 | // * Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above 11 | // copyright notice, this list of conditions and the following disclaimer 12 | // in the documentation and/or other materials provided with the 13 | // distribution. 14 | // * Neither the name of Google Inc. nor the names of its 15 | // contributors may be used to endorse or promote products derived from 16 | // this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | // 30 | // Author: wan@google.com (Zhanyong Wan) 31 | // 32 | // Google C++ Mocking Framework (Google Mock) 33 | // 34 | // This file #includes all Google Mock implementation .cc files. The 35 | // purpose is to allow a user to build Google Mock by compiling this 36 | // file alone. 37 | 38 | // This line ensures that gmock.h can be compiled on its own, even 39 | // when it's fused. 40 | #include "gmock/gmock.h" 41 | 42 | // The following lines pull in the real gmock *.cc files. 43 | #include "src/gmock-cardinalities.cc" 44 | #include "src/gmock-internal-utils.cc" 45 | #include "src/gmock-matchers.cc" 46 | #include "src/gmock-spec-builders.cc" 47 | #include "src/gmock.cc" 48 | -------------------------------------------------------------------------------- /cxx/external/unittest/googletest/src/gtest-all.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2008, Google Inc. 2 | // All rights reserved. 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are 6 | // met: 7 | // 8 | // * Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above 11 | // copyright notice, this list of conditions and the following disclaimer 12 | // in the documentation and/or other materials provided with the 13 | // distribution. 14 | // * Neither the name of Google Inc. nor the names of its 15 | // contributors may be used to endorse or promote products derived from 16 | // this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | // 30 | // Author: mheule@google.com (Markus Heule) 31 | // 32 | // Google C++ Testing Framework (Google Test) 33 | // 34 | // Sometimes it's desirable to build Google Test by compiling a single file. 35 | // This file serves this purpose. 36 | 37 | // This line ensures that gtest.h can be compiled on its own, even 38 | // when it's fused. 39 | #include "gtest/gtest.h" 40 | 41 | // The following lines pull in the real gtest *.cc files. 42 | #include "src/gtest.cc" 43 | #include "src/gtest-death-test.cc" 44 | #include "src/gtest-filepath.cc" 45 | #include "src/gtest-port.cc" 46 | #include "src/gtest-printers.cc" 47 | #include "src/gtest-test-part.cc" 48 | #include "src/gtest-typed-test.cc" 49 | -------------------------------------------------------------------------------- /cxx/external/unittest/googlemock/include/gmock/internal/custom/gmock-port.h: -------------------------------------------------------------------------------- 1 | // Copyright 2015, Google Inc. 2 | // All rights reserved. 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are 6 | // met: 7 | // 8 | // * Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above 11 | // copyright notice, this list of conditions and the following disclaimer 12 | // in the documentation and/or other materials provided with the 13 | // distribution. 14 | // * Neither the name of Google Inc. nor the names of its 15 | // contributors may be used to endorse or promote products derived from 16 | // this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | // 30 | // Injection point for custom user configurations. 31 | // The following macros can be defined: 32 | // 33 | // Flag related macros: 34 | // GMOCK_DECLARE_bool_(name) 35 | // GMOCK_DECLARE_int32_(name) 36 | // GMOCK_DECLARE_string_(name) 37 | // GMOCK_DEFINE_bool_(name, default_val, doc) 38 | // GMOCK_DEFINE_int32_(name, default_val, doc) 39 | // GMOCK_DEFINE_string_(name, default_val, doc) 40 | // 41 | // ** Custom implementation starts here ** 42 | 43 | #ifndef GMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_PORT_H_ 44 | #define GMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_PORT_H_ 45 | 46 | #endif // GMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_PORT_H_ 47 | -------------------------------------------------------------------------------- /cxx/include/s2020/AST/Number.h: -------------------------------------------------------------------------------- 1 | #ifndef SCHEME2020_AST_NUMBER_H 2 | #define SCHEME2020_AST_NUMBER_H 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | namespace llvm { 9 | class raw_ostream; 10 | } // namespace llvm 11 | 12 | namespace s2020 { 13 | namespace ast { 14 | 15 | class ASTContext; 16 | 17 | enum class NumberKind : uint8_t { 18 | exact, 19 | inexact, 20 | }; 21 | 22 | using ExactNumberT = int64_t; 23 | using InexactNumberT = double; 24 | 25 | class Number { 26 | public: 27 | Number() : kind_(NumberKind::exact), exact_(0) {} 28 | 29 | NumberKind getKind() const { 30 | return kind_; 31 | } 32 | bool isExact() const { 33 | return kind_ == NumberKind::exact; 34 | } 35 | bool isInexact() const { 36 | return kind_ == NumberKind::inexact; 37 | } 38 | 39 | ExactNumberT getExact() const { 40 | assert(kind_ == NumberKind::exact); 41 | return exact_; 42 | } 43 | InexactNumberT getInexact() const { 44 | assert(kind_ == NumberKind::inexact); 45 | return inexact_; 46 | } 47 | 48 | /// \return true if the two numbers are the same kind and have the same 49 | /// bit pattern. 50 | bool equals(const Number &other) const { 51 | static_assert( 52 | sizeof(exact_) == sizeof(inexact_), 53 | "comparison relies on exact and inexact being the same size"); 54 | return kind_ == other.kind_ && 55 | memcmp(&exact_, &other.exact_, sizeof(exact_)) == 0; 56 | } 57 | 58 | bool operator==(const Number &other) const { 59 | return equals(other); 60 | } 61 | 62 | bool exactEquals(ExactNumberT o) const { 63 | return kind_ == NumberKind::exact && exact_ == o; 64 | } 65 | 66 | bool inexactEquals(const InexactNumberT &o) const { 67 | return kind_ == NumberKind::inexact && 68 | memcmp(&inexact_, &o, sizeof(inexact_)) == 0; 69 | } 70 | 71 | private: 72 | friend class ASTContext; 73 | explicit Number(ExactNumberT exact) 74 | : kind_(NumberKind::exact), exact_(exact) {} 75 | explicit Number(InexactNumberT inexact) 76 | : kind_(NumberKind::inexact), inexact_(inexact) {} 77 | 78 | private: 79 | NumberKind kind_; 80 | union { 81 | ExactNumberT exact_; 82 | InexactNumberT inexact_; 83 | }; 84 | }; 85 | 86 | llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const Number &number); 87 | 88 | } // namespace ast 89 | } // namespace s2020 90 | 91 | #endif // SCHEME2020_AST_NUMBER_H 92 | -------------------------------------------------------------------------------- /cxx/lib/Parser/genCharTab.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | from __future__ import print_function 4 | 5 | tab = [[] for i in range(0, 256)] 6 | 7 | 8 | def addSingleTag(tag, i): 9 | if not tab[i].count(tag): 10 | tab[i].append(tag) 11 | 12 | 13 | def addTag(tag, i): 14 | if type(tag) is tuple: 15 | for t in tag: 16 | addTag(t, i) 17 | else: 18 | addSingleTag(tag, i) 19 | 20 | 21 | def addRange(tag, a, b): 22 | if type(a) is str: 23 | a = ord(a) 24 | if type(b) is str: 25 | b = ord(b) 26 | for i in range(a, b + 1): 27 | addTag(tag, i) 28 | 29 | 30 | def add(tag, *elems): 31 | for i in elems: 32 | if type(i) is str: 33 | i = ord(i) 34 | addTag(tag, i) 35 | 36 | 37 | def genTable(): 38 | for i in range(0, 256): 39 | print(" /* %3d, " % i, end="") 40 | if i < 32 or i >= 127: 41 | print("0x%02x" % i, end="") 42 | else: 43 | print("'%s' " % chr(i), end="") 44 | print(" */ ", end="") 45 | 46 | prev = False 47 | tab[i].sort() 48 | for j in tab[i]: 49 | if prev: 50 | print(" | ", end="") 51 | prev = True 52 | print(j, end="") 53 | if not prev: 54 | print(0, end="") 55 | print(",") 56 | 57 | 58 | SUBSEQUENT = "CC::Subsequent" 59 | DELIMITER = "CC::Delimiter" 60 | WHITESPACE = ("CC::WhitespaceClass", DELIMITER) 61 | UTF8 = "CC::UTF8Class" 62 | PECULIAR_IDENT = "CC::PeculiarIdentClass" 63 | 64 | DOT_SUBSEQUENT = "CC::DotSubsequent" 65 | SIGN_SUBSEQUENT = ("CC::SignSubsequent", DOT_SUBSEQUENT) 66 | INITIAL = ("CC::InitialClass", SIGN_SUBSEQUENT) 67 | 68 | DIGIT = "CC::DigitClass" 69 | HASH = "CC::HashClass" 70 | 71 | addRange(INITIAL, 'a', 'z') 72 | addRange(INITIAL, 'A', 'Z') 73 | add(INITIAL, '!', '$', '%', '&', '*', '/', ':', '<', '=', '>', '?', '^', '_', 74 | '~', '@') 75 | 76 | addRange(SUBSEQUENT, 'a', 'z') 77 | addRange(SUBSEQUENT, 'A', 'Z') 78 | add(SUBSEQUENT, '!', '$', '%', '&', '*', '/', ':', '<', '=', '>', '?', '^', '_', 79 | '~') 80 | addRange(SUBSEQUENT, '0', '9') 81 | add(SUBSEQUENT, '+', '-', '.', '@') 82 | 83 | add(WHITESPACE, ' ', '\n', '\r', '\v', '\t') 84 | 85 | add(PECULIAR_IDENT, '+', '-', '.') 86 | add(SIGN_SUBSEQUENT, '+', '-', '@') 87 | add(DOT_SUBSEQUENT, '.') 88 | 89 | addRange(DIGIT, '0', '9') 90 | add(DELIMITER, '|', '(', ')', '[', ']', '{', '}', '"', ';') 91 | 92 | add(HASH, '#') 93 | addRange(UTF8, 128, 255) 94 | 95 | genTable() 96 | -------------------------------------------------------------------------------- /cxx/external/unittest/googletest/include/gtest/gtest_prod.h: -------------------------------------------------------------------------------- 1 | // Copyright 2006, Google Inc. 2 | // All rights reserved. 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are 6 | // met: 7 | // 8 | // * Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above 11 | // copyright notice, this list of conditions and the following disclaimer 12 | // in the documentation and/or other materials provided with the 13 | // distribution. 14 | // * Neither the name of Google Inc. nor the names of its 15 | // contributors may be used to endorse or promote products derived from 16 | // this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | // 30 | // Author: wan@google.com (Zhanyong Wan) 31 | // 32 | // Google C++ Testing Framework definitions useful in production code. 33 | 34 | #ifndef GTEST_INCLUDE_GTEST_GTEST_PROD_H_ 35 | #define GTEST_INCLUDE_GTEST_GTEST_PROD_H_ 36 | 37 | // When you need to test the private or protected members of a class, 38 | // use the FRIEND_TEST macro to declare your tests as friends of the 39 | // class. For example: 40 | // 41 | // class MyClass { 42 | // private: 43 | // void MyMethod(); 44 | // FRIEND_TEST(MyClassTest, MyMethod); 45 | // }; 46 | // 47 | // class MyClassTest : public testing::Test { 48 | // // ... 49 | // }; 50 | // 51 | // TEST_F(MyClassTest, MyMethod) { 52 | // // Can call MyClass::MyMethod() here. 53 | // } 54 | 55 | #define FRIEND_TEST(test_case_name, test_name)\ 56 | friend class test_case_name##_##test_name##_Test 57 | 58 | #endif // GTEST_INCLUDE_GTEST_GTEST_PROD_H_ 59 | -------------------------------------------------------------------------------- /cxx/external/unittest/googlemock/include/gmock/gmock-more-matchers.h: -------------------------------------------------------------------------------- 1 | // Copyright 2013, Google Inc. 2 | // All rights reserved. 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are 6 | // met: 7 | // 8 | // * Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above 11 | // copyright notice, this list of conditions and the following disclaimer 12 | // in the documentation and/or other materials provided with the 13 | // distribution. 14 | // * Neither the name of Google Inc. nor the names of its 15 | // contributors may be used to endorse or promote products derived from 16 | // this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | // 30 | // Author: marcus.boerger@google.com (Marcus Boerger) 31 | 32 | // Google Mock - a framework for writing C++ mock classes. 33 | // 34 | // This file implements some matchers that depend on gmock-generated-matchers.h. 35 | // 36 | // Note that tests are implemented in gmock-matchers_test.cc rather than 37 | // gmock-more-matchers-test.cc. 38 | 39 | #ifndef GMOCK_GMOCK_MORE_MATCHERS_H_ 40 | #define GMOCK_GMOCK_MORE_MATCHERS_H_ 41 | 42 | #include "gmock/gmock-generated-matchers.h" 43 | 44 | namespace testing { 45 | 46 | // Defines a matcher that matches an empty container. The container must 47 | // support both size() and empty(), which all STL-like containers provide. 48 | MATCHER(IsEmpty, negation ? "isn't empty" : "is empty") { 49 | if (arg.empty()) { 50 | return true; 51 | } 52 | *result_listener << "whose size is " << arg.size(); 53 | return false; 54 | } 55 | 56 | } // namespace testing 57 | 58 | #endif // GMOCK_GMOCK_MORE_MATCHERS_H_ 59 | -------------------------------------------------------------------------------- /.clang-format: -------------------------------------------------------------------------------- 1 | --- 2 | AccessModifierOffset: -1 3 | AlignAfterOpenBracket: AlwaysBreak 4 | AlignConsecutiveAssignments: false 5 | AlignConsecutiveDeclarations: false 6 | AlignEscapedNewlinesLeft: true 7 | AlignOperands: false 8 | AlignTrailingComments: false 9 | AllowAllParametersOfDeclarationOnNextLine: false 10 | AllowShortBlocksOnASingleLine: false 11 | AllowShortCaseLabelsOnASingleLine: false 12 | AllowShortFunctionsOnASingleLine: Empty 13 | AllowShortIfStatementsOnASingleLine: false 14 | AllowShortLoopsOnASingleLine: false 15 | AlwaysBreakAfterReturnType: None 16 | AlwaysBreakBeforeMultilineStrings: true 17 | AlwaysBreakTemplateDeclarations: true 18 | BinPackArguments: false 19 | BinPackParameters: false 20 | BraceWrapping: 21 | AfterClass: false 22 | AfterControlStatement: false 23 | AfterEnum: false 24 | AfterFunction: false 25 | AfterNamespace: false 26 | AfterObjCDeclaration: false 27 | AfterStruct: false 28 | AfterUnion: false 29 | BeforeCatch: false 30 | BeforeElse: false 31 | IndentBraces: false 32 | BreakBeforeBinaryOperators: None 33 | BreakBeforeBraces: Attach 34 | BreakBeforeTernaryOperators: true 35 | BreakConstructorInitializersBeforeComma: false 36 | BreakAfterJavaFieldAnnotations: false 37 | BreakStringLiterals: false 38 | ColumnLimit: 80 39 | CommentPragmas: '^ IWYU pragma:' 40 | ConstructorInitializerAllOnOneLineOrOnePerLine: true 41 | ConstructorInitializerIndentWidth: 4 42 | ContinuationIndentWidth: 4 43 | Cpp11BracedListStyle: true 44 | DerivePointerAlignment: false 45 | DisableFormat: false 46 | ForEachMacros: [ FOR_EACH_RANGE, FOR_EACH, ] 47 | IncludeCategories: 48 | - Regex: '^<.*\.h(pp)?>' 49 | Priority: 1 50 | - Regex: '^<.*' 51 | Priority: 2 52 | - Regex: '.*' 53 | Priority: 3 54 | IndentCaseLabels: true 55 | IndentWidth: 2 56 | IndentWrappedFunctionNames: false 57 | KeepEmptyLinesAtTheStartOfBlocks: false 58 | MacroBlockBegin: '' 59 | MacroBlockEnd: '' 60 | MaxEmptyLinesToKeep: 1 61 | NamespaceIndentation: None 62 | ObjCBlockIndentWidth: 2 63 | ObjCSpaceAfterProperty: false 64 | ObjCSpaceBeforeProtocolList: false 65 | PenaltyBreakBeforeFirstCallParameter: 1 66 | PenaltyBreakComment: 300 67 | PenaltyBreakFirstLessLess: 120 68 | PenaltyBreakString: 1000 69 | PenaltyExcessCharacter: 1000000 70 | PenaltyReturnTypeOnItsOwnLine: 200 71 | PointerAlignment: Right 72 | ReflowComments: true 73 | SortIncludes: true 74 | SpaceAfterCStyleCast: false 75 | SpaceBeforeAssignmentOperators: true 76 | SpaceBeforeParens: ControlStatements 77 | SpaceInEmptyParentheses: false 78 | SpacesBeforeTrailingComments: 1 79 | SpacesInAngles: false 80 | SpacesInContainerLiterals: true 81 | SpacesInCStyleCastParentheses: false 82 | SpacesInParentheses: false 83 | SpacesInSquareBrackets: false 84 | Standard: Cpp11 85 | TabWidth: 8 86 | UseTab: Never 87 | ... 88 | -------------------------------------------------------------------------------- /cxx/unittests/Parser/DatumParserTest.cpp: -------------------------------------------------------------------------------- 1 | #include "s2020/Parser/DatumParser.h" 2 | 3 | #include "DiagContext.h" 4 | 5 | #include 6 | 7 | using namespace s2020; 8 | using namespace s2020::parser; 9 | using namespace s2020::ast; 10 | 11 | namespace { 12 | 13 | class DatumParserTest : public ::testing::Test { 14 | protected: 15 | const llvm::MemoryBuffer &makeBuf(const char *str) { 16 | auto id = context_.sm.addNewSourceBuffer( 17 | llvm::MemoryBuffer::getMemBuffer(str, "input", true)); 18 | return *context_.sm.getSourceBuffer(id); 19 | } 20 | 21 | NumberNode *Num(ExactNumberT n) { 22 | return new (context_) NumberNode(context_.makeExactNumber(n)); 23 | } 24 | SymbolNode *Sym(StringRef name) { 25 | return new (context_) SymbolNode(context_.stringTable.getIdentifier(name)); 26 | } 27 | 28 | protected: 29 | ASTContext context_{}; 30 | }; 31 | 32 | TEST_F(DatumParserTest, PrintTest) { 33 | auto res = parseDatums( 34 | context_, 35 | makeBuf("hello 10" 36 | " (list -10 more)" 37 | " (a . b)" 38 | " (1 2 3 . 4)" 39 | " (10 . (20 . (30 . ())))" 40 | " (if [> a 10] (display 1) (display a))")); 41 | ASSERT_TRUE(res.hasValue()); 42 | 43 | std::string str; 44 | llvm::raw_string_ostream OS{str}; 45 | for (const auto *node : res.getValue()) 46 | dump(OS, node); 47 | OS.flush(); 48 | ASSERT_EQ( 49 | "hello\n" 50 | "10\n" 51 | "(list\n" 52 | " -10\n" 53 | " more)\n" 54 | "(a . b)\n" 55 | "(1\n" 56 | " 2\n" 57 | " 3 . 4)\n" 58 | "(10\n" 59 | " 20\n" 60 | " 30)\n" 61 | "(if\n" 62 | " (>\n" 63 | " a\n" 64 | " 10)\n" 65 | " (display\n" 66 | " 1)\n" 67 | " (display\n" 68 | " a))\n", 69 | str); 70 | } 71 | 72 | TEST_F(DatumParserTest, SmokeTest) { 73 | auto parsed = parseDatums( 74 | context_, 75 | makeBuf("(hello " 76 | " 10" 77 | " (list -10 more)" 78 | " (a . b)" 79 | " (1 2 3 . 4)" 80 | " (10 . (20 . (30 . ())))" 81 | " (if [> a 10] (display 1) (display a)))")); 82 | ASSERT_TRUE(parsed.hasValue()); 83 | ASSERT_EQ(1, parsed.getValue().size()); 84 | 85 | auto *l = list( 86 | context_, 87 | Sym("hello"), 88 | Num(10), 89 | list(context_, Sym("list"), Num(-10), Sym("more")), 90 | cons(context_, Sym("a"), Sym("b")), 91 | cons( 92 | context_, 93 | Num(1), 94 | cons(context_, Num(2), cons(context_, Num(3), Num(4)))), 95 | list(context_, Num(10), Num(20), Num(30)), 96 | list( 97 | context_, 98 | Sym("if"), 99 | list(context_, Sym(">"), Sym("a"), Num(10)), 100 | list(context_, Sym("display"), Num(1)), 101 | list(context_, Sym("display"), Sym("a")))); 102 | 103 | ASSERT_TRUE(deepEqual(parsed.getValue().at(0), l)); 104 | } 105 | 106 | } // anonymous namespace -------------------------------------------------------------------------------- /cxx/external/unittest/googletest/include/gtest/internal/custom/gtest-port.h: -------------------------------------------------------------------------------- 1 | // Copyright 2015, Google Inc. 2 | // All rights reserved. 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are 6 | // met: 7 | // 8 | // * Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above 11 | // copyright notice, this list of conditions and the following disclaimer 12 | // in the documentation and/or other materials provided with the 13 | // distribution. 14 | // * Neither the name of Google Inc. nor the names of its 15 | // contributors may be used to endorse or promote products derived from 16 | // this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | // 30 | // Injection point for custom user configurations. 31 | // The following macros can be defined: 32 | // 33 | // Flag related macros: 34 | // GTEST_FLAG(flag_name) 35 | // GTEST_USE_OWN_FLAGFILE_FLAG_ - Define to 0 when the system provides its 36 | // own flagfile flag parsing. 37 | // GTEST_DECLARE_bool_(name) 38 | // GTEST_DECLARE_int32_(name) 39 | // GTEST_DECLARE_string_(name) 40 | // GTEST_DEFINE_bool_(name, default_val, doc) 41 | // GTEST_DEFINE_int32_(name, default_val, doc) 42 | // GTEST_DEFINE_string_(name, default_val, doc) 43 | // 44 | // Test filtering: 45 | // GTEST_TEST_FILTER_ENV_VAR_ - The name of an environment variable that 46 | // will be used if --GTEST_FLAG(test_filter) 47 | // is not provided. 48 | // 49 | // Logging: 50 | // GTEST_LOG_(severity) 51 | // GTEST_CHECK_(condition) 52 | // Functions LogToStderr() and FlushInfoLog() have to be provided too. 53 | // 54 | // Threading: 55 | // GTEST_HAS_NOTIFICATION_ - Enabled if Notification is already provided. 56 | // GTEST_HAS_MUTEX_AND_THREAD_LOCAL_ - Enabled if Mutex and ThreadLocal are 57 | // already provided. 58 | // Must also provide GTEST_DECLARE_STATIC_MUTEX_(mutex) and 59 | // GTEST_DEFINE_STATIC_MUTEX_(mutex) 60 | // 61 | // GTEST_EXCLUSIVE_LOCK_REQUIRED_(locks) 62 | // GTEST_LOCK_EXCLUDED_(locks) 63 | // 64 | // ** Custom implementation starts here ** 65 | 66 | #ifndef GTEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_PORT_H_ 67 | #define GTEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_PORT_H_ 68 | 69 | #endif // GTEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_PORT_H_ 70 | -------------------------------------------------------------------------------- /cxx/include/s2020/Support/CharacterProperties.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Facebook, Inc. and its affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #ifndef S2020_PLATFORMUNICODE_CHARACTERPROPERTIES_H 9 | #define S2020_PLATFORMUNICODE_CHARACTERPROPERTIES_H 10 | 11 | #include 12 | #include 13 | 14 | namespace s2020 { 15 | 16 | const uint32_t UNICODE_MAX_VALUE = 0x10FFFF; 17 | /// The start of the surrogate range. 18 | const uint32_t UNICODE_SURROGATE_FIRST = 0xD800; 19 | /// The last character of the surrogate range (inclusive). 20 | const uint32_t UNICODE_SURROGATE_LAST = 0xDFFF; 21 | const uint32_t UTF16_HIGH_SURROGATE = 0xD800; 22 | const uint32_t UTF16_LOW_SURROGATE = 0xDC00; 23 | const uint32_t UNICODE_REPLACEMENT_CHARACTER = 0xFFFD; 24 | /// The last member of the BMP. 25 | const uint32_t UNICODE_LAST_BMP = 0xFFFF; 26 | 27 | const uint32_t UNICODE_LINE_SEPARATOR = 0x2028; 28 | const uint32_t UNICODE_PARAGRAPH_SEPARATOR = 0x2029; 29 | 30 | const uint32_t UNICODE_ZWNJ = 0x200C; 31 | const uint32_t UNICODE_ZWJ = 0x200D; 32 | 33 | /// The maximum number of precanonicalizations of any character. 34 | /// Precanonicalization is not a term from the Unicode spec; rather it refers to 35 | /// the RegExp Canonicalize function given in ES5.1 15.10.2.8. Most characters 36 | /// are either canonicalized to by themselves or their lowercase variant; 37 | /// there's a handful of exceptions which are tracked here. 38 | const uint32_t UNICODE_MAX_PRECANONICALIZATIONS = 3; 39 | 40 | inline bool isValidCodePoint(uint32_t cp) { 41 | return !( 42 | (cp >= UNICODE_SURROGATE_FIRST && cp <= UNICODE_SURROGATE_LAST) || 43 | cp > UNICODE_MAX_VALUE); 44 | } 45 | 46 | /// \return whether \p cp is part of the Basic Multilingual Plane. 47 | /// Surrogate characters are considered part of the BMP. 48 | inline bool isMemberOfBMP(uint32_t cp) { 49 | return cp <= UNICODE_LAST_BMP; 50 | } 51 | 52 | /// \return whether cp is a high surrogate. 53 | inline bool isHighSurrogate(uint32_t cp) { 54 | return UNICODE_SURROGATE_FIRST <= cp && cp < UTF16_LOW_SURROGATE; 55 | } 56 | 57 | /// \return whether cp is a low surrogate. 58 | inline bool isLowSurrogate(uint32_t cp) { 59 | return UTF16_LOW_SURROGATE <= cp && cp <= UNICODE_SURROGATE_LAST; 60 | } 61 | 62 | /// Decode a surrogate pair [\p hi, \p lo] into a code point. 63 | inline uint32_t decodeSurrogatePair(uint32_t hi, uint32_t lo) { 64 | assert(isHighSurrogate(hi) && isLowSurrogate(lo) && "Not a surrogate pair"); 65 | return ((hi - UTF16_HIGH_SURROGATE) << 10) + (lo - UTF16_LOW_SURROGATE) + 66 | 0x10000; 67 | } 68 | 69 | /// \return true if the codepoint is not ASCII and is a Unicode letter. 70 | bool isUnicodeOnlyLetter(uint32_t cp); 71 | /// \return true if the codepoint is not ASCII and is a Unicode space. 72 | bool isUnicodeOnlySpace(uint32_t cp); 73 | /// \return true if the codepoint is in the Non-Spacing Mark or 74 | /// Combining-Spacing Mark categories. 75 | bool isUnicodeCombiningMark(uint32_t cp); 76 | /// \return true if the codepoint is in the Decimal Number category. 77 | bool isUnicodeDigit(uint32_t cp); 78 | /// \return true if the codepoint is in the Connector Punctuation category. 79 | bool isUnicodeConnectorPunctuation(uint32_t cp); 80 | 81 | /// \return the canonicalized value of \p cp, following ES9 21.2.2.8.2. 82 | uint32_t canonicalize(uint32_t cp, bool unicode); 83 | 84 | class CodePointSet; 85 | /// \return a set containing all characters which are canonically equivalent to 86 | /// any character in \p set, following ES9 21.2.2.8.2. 87 | CodePointSet makeCanonicallyEquivalent(const CodePointSet &set, bool unicode); 88 | 89 | } // namespace s2020 90 | 91 | #endif // S2020_PLATFORMUNICODE_CHARACTERPROPERTIES_H 92 | -------------------------------------------------------------------------------- /cmake/Lit.cmake: -------------------------------------------------------------------------------- 1 | # Copyright (c) Facebook, Inc. and its affiliates. 2 | # 3 | # This source code is licensed under the MIT license found in the 4 | # LICENSE file in the root directory of this source tree. 5 | 6 | set(S2020_LIT_PATH "${S2020_TOOLS_OUTPUT_DIR}/s2020-lit") 7 | if (CMAKE_HOST_WIN32 AND NOT CYGWIN) 8 | # llvm-lit needs suffix.py for multiprocess to find a main module. 9 | set(S2020_LIT_PATH "${S2020_LIT_PATH}.py") 10 | endif () 11 | 12 | 13 | # A raw function to create a lit target. This is used to implement the testuite 14 | # management functions. 15 | function(add_lit_target target comment) 16 | cmake_parse_arguments(ARG "" "" "PARAMS;DEPENDS;ARGS" ${ARGN}) 17 | set(LIT_ARGS "${ARG_ARGS} ${LLVH_LIT_ARGS}") 18 | separate_arguments(LIT_ARGS) 19 | if (NOT CMAKE_CFG_INTDIR STREQUAL ".") 20 | list(APPEND LIT_ARGS --param build_mode=${CMAKE_CFG_INTDIR}) 21 | endif () 22 | 23 | set(LIT_COMMAND "${PYTHON_EXECUTABLE};${S2020_LIT_PATH}") 24 | list(APPEND LIT_COMMAND ${LIT_ARGS}) 25 | foreach(param ${ARG_PARAMS}) 26 | list(APPEND LIT_COMMAND --param ${param}) 27 | endforeach() 28 | if (ARG_UNPARSED_ARGUMENTS) 29 | add_custom_target(${target} 30 | COMMAND ${LIT_COMMAND} ${ARG_UNPARSED_ARGUMENTS} 31 | COMMENT "${comment}" 32 | USES_TERMINAL 33 | ) 34 | else() 35 | add_custom_target(${target} 36 | COMMAND ${CMAKE_COMMAND} -E echo "${target} does nothing, no tools built.") 37 | message(STATUS "${target} does nothing.") 38 | endif() 39 | 40 | # Add lit test dependencies. 41 | set(llvm_utils_deps 42 | FileCheck count not 43 | ) 44 | foreach(dep ${llvm_utils_deps}) 45 | if (TARGET ${dep}) 46 | add_dependencies(${target} ${dep}) 47 | endif() 48 | endforeach() 49 | 50 | if (ARG_DEPENDS) 51 | add_dependencies(${target} ${ARG_DEPENDS}) 52 | endif() 53 | 54 | # Tests should be excluded from "Build Solution". 55 | set_target_properties(${target} PROPERTIES EXCLUDE_FROM_DEFAULT_BUILD ON) 56 | endfunction() 57 | 58 | # A function to add a set of lit test suites to be driven through 'check-*' targets. 59 | function(add_lit_testsuite target comment) 60 | cmake_parse_arguments(ARG "" "" "PARAMS;DEPENDS;ARGS" ${ARGN}) 61 | 62 | # Produce a specific suffixed check rule. 63 | add_lit_target(${target} ${comment} 64 | ${ARG_UNPARSED_ARGUMENTS} 65 | PARAMS ${ARG_PARAMS} 66 | DEPENDS ${ARG_DEPENDS} 67 | ARGS ${ARG_ARGS} 68 | ) 69 | endfunction() 70 | 71 | function(add_unittest test_suite test_name) 72 | # Our current version of gtest does not properly recognize C++11 support 73 | # with MSVC, so it falls back to tr1 / experimental classes. Since LLVM 74 | # itself requires C++11, we can safely force it on unconditionally so that 75 | # we don't have to fight with the buggy gtest check. 76 | add_definitions(-DGTEST_LANG_CXX11=1) 77 | add_definitions(-DGTEST_HAS_TR1_TUPLE=0) 78 | 79 | include_directories(${CMAKE_SOURCE_DIR}/cxx/external/unittest/googletest/include) 80 | include_directories(${CMAKE_SOURCE_DIR}/cxx/external/unittest/googlemock/include) 81 | 82 | # if (SUPPORTS_VARIADIC_MACROS_FLAG) 83 | # list(APPEND LLVM_COMPILE_FLAGS "-Wno-variadic-macros") 84 | # endif () 85 | # # Some parts of gtest rely on this GNU extension, don't warn on it. 86 | # if(SUPPORTS_GNU_ZERO_VARIADIC_MACRO_ARGUMENTS_FLAG) 87 | # list(APPEND LLVM_COMPILE_FLAGS "-Wno-gnu-zero-variadic-macro-arguments") 88 | # endif() 89 | 90 | add_s2020_executable(${test_name} ${ARGN}) 91 | 92 | target_link_libraries(${test_name} PRIVATE gtest_main gtest) 93 | 94 | add_dependencies(${test_suite} ${test_name}) 95 | get_target_property(test_suite_folder ${test_suite} FOLDER) 96 | if (NOT ${test_suite_folder} STREQUAL "NOTFOUND") 97 | set_property(TARGET ${test_name} PROPERTY FOLDER "${test_suite_folder}") 98 | endif () 99 | endfunction() 100 | -------------------------------------------------------------------------------- /cxx/external/unittest/googlemock/include/gmock/gmock.h: -------------------------------------------------------------------------------- 1 | // Copyright 2007, Google Inc. 2 | // All rights reserved. 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are 6 | // met: 7 | // 8 | // * Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above 11 | // copyright notice, this list of conditions and the following disclaimer 12 | // in the documentation and/or other materials provided with the 13 | // distribution. 14 | // * Neither the name of Google Inc. nor the names of its 15 | // contributors may be used to endorse or promote products derived from 16 | // this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | // 30 | // Author: wan@google.com (Zhanyong Wan) 31 | 32 | // Google Mock - a framework for writing C++ mock classes. 33 | // 34 | // This is the main header file a user should include. 35 | 36 | #ifndef GMOCK_INCLUDE_GMOCK_GMOCK_H_ 37 | #define GMOCK_INCLUDE_GMOCK_GMOCK_H_ 38 | 39 | // This file implements the following syntax: 40 | // 41 | // ON_CALL(mock_object.Method(...)) 42 | // .With(...) ? 43 | // .WillByDefault(...); 44 | // 45 | // where With() is optional and WillByDefault() must appear exactly 46 | // once. 47 | // 48 | // EXPECT_CALL(mock_object.Method(...)) 49 | // .With(...) ? 50 | // .Times(...) ? 51 | // .InSequence(...) * 52 | // .WillOnce(...) * 53 | // .WillRepeatedly(...) ? 54 | // .RetiresOnSaturation() ? ; 55 | // 56 | // where all clauses are optional and WillOnce() can be repeated. 57 | 58 | #include "gmock/gmock-actions.h" 59 | #include "gmock/gmock-cardinalities.h" 60 | #include "gmock/gmock-generated-actions.h" 61 | #include "gmock/gmock-generated-function-mockers.h" 62 | #include "gmock/gmock-generated-nice-strict.h" 63 | #include "gmock/gmock-generated-matchers.h" 64 | #include "gmock/gmock-matchers.h" 65 | #include "gmock/gmock-more-actions.h" 66 | #include "gmock/gmock-more-matchers.h" 67 | #include "gmock/internal/gmock-internal-utils.h" 68 | 69 | namespace testing { 70 | 71 | // Declares Google Mock flags that we want a user to use programmatically. 72 | GMOCK_DECLARE_bool_(catch_leaked_mocks); 73 | GMOCK_DECLARE_string_(verbose); 74 | 75 | // Initializes Google Mock. This must be called before running the 76 | // tests. In particular, it parses the command line for the flags 77 | // that Google Mock recognizes. Whenever a Google Mock flag is seen, 78 | // it is removed from argv, and *argc is decremented. 79 | // 80 | // No value is returned. Instead, the Google Mock flag variables are 81 | // updated. 82 | // 83 | // Since Google Test is needed for Google Mock to work, this function 84 | // also initializes Google Test and parses its flags, if that hasn't 85 | // been done. 86 | GTEST_API_ void InitGoogleMock(int* argc, char** argv); 87 | 88 | // This overloaded version can be used in Windows programs compiled in 89 | // UNICODE mode. 90 | GTEST_API_ void InitGoogleMock(int* argc, wchar_t** argv); 91 | 92 | } // namespace testing 93 | 94 | #endif // GMOCK_INCLUDE_GMOCK_GMOCK_H_ 95 | -------------------------------------------------------------------------------- /cxx/external/unittest/googletest/include/gtest/internal/custom/raw-ostream.h: -------------------------------------------------------------------------------- 1 | //===-- raw-ostream.h - Support for printing using raw_ostream --*- C++ -*-===// 2 | // 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 | // See https://llvm.org/LICENSE.txt for license information. 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 | // 7 | //===----------------------------------------------------------------------===// 8 | // This file is not part of gtest, but extends it to support LLVM libraries. 9 | // This is not a public API for testing - it's a detail of LLVM's gtest. 10 | // 11 | // gtest allows providing printers for custom types by defining operator<<. 12 | // In LLVM, operator<< usually takes llvm:raw_ostream& instead of std::ostream&. 13 | // 14 | // This file defines a template printable(V), which returns a version of V that 15 | // can be streamed into a std::ostream. 16 | // 17 | // This interface is chosen so that in the default case (printable(V) is V), 18 | // the main gtest code calls operator<<(OS, V) itself. gtest-printers carefully 19 | // controls the lookup to enable fallback printing (see testing::internal2). 20 | //===----------------------------------------------------------------------===// 21 | 22 | #ifndef GTEST_INCLUDE_GTEST_INTERNAL_CUSTOM_RAW_OSTREAM_H_ 23 | #define GTEST_INCLUDE_GTEST_INTERNAL_CUSTOM_RAW_OSTREAM_H_ 24 | 25 | namespace llvm_gtest { 26 | // StreamSwitch is a trait that tells us how to stream a T into a std::ostream. 27 | // By default, we just stream the T directly. We'll specialize this later. 28 | template struct StreamSwitch { 29 | static const T& printable(const T& V) { return V; } 30 | }; 31 | 32 | // printable() returns a version of its argument that can be streamed into a 33 | // std::ostream. This may be the argument itself, or some other representation. 34 | template 35 | auto printable(const T &V) -> decltype(StreamSwitch::printable(V)) { 36 | // We delegate to the trait, to allow partial specialization. 37 | return StreamSwitch::printable(V); 38 | } 39 | } // namespace llvm_gtest 40 | 41 | // If raw_ostream support is enabled, we specialize for types with operator<< 42 | // that takes a raw_ostream. 43 | #if !GTEST_NO_LLVM_RAW_OSTREAM 44 | #include "llvm/ADT/Optional.h" 45 | #include "llvm/Support/raw_os_ostream.h" 46 | #include "llvm/Support/raw_ostream.h" 47 | #include 48 | namespace llvm_gtest { 49 | 50 | // The printable() of a raw_ostream-enabled type T is a RawStreamProxy. 51 | // It uses raw_os_ostream to write the wrapped value to a std::ostream. 52 | template 53 | struct RawStreamProxy { 54 | const T& V; 55 | friend std::ostream &operator<<(std::ostream &S, const RawStreamProxy &V) { 56 | llvm::raw_os_ostream OS(S); 57 | OS << V.V; 58 | return S; 59 | } 60 | }; 61 | 62 | // We enable raw_ostream treatment if `(raw_ostream&) << (const T&)` is valid. 63 | // We don't want implicit conversions on the RHS (e.g. to bool!), so "consume" 64 | // the possible conversion by passing something convertible to const T& instead. 65 | template struct ConvertibleTo { operator T(); }; 66 | template 67 | struct StreamSwitch() 68 | << ConvertibleTo()))> { 69 | static const RawStreamProxy printable(const T &V) { return {V}; } 70 | }; 71 | 72 | // llvm::Optional has a template operator<<, which means it will not accept any 73 | // implicit conversions, so we need to special-case it here. 74 | template 75 | struct StreamSwitch, 76 | decltype((void)(std::declval() 77 | << std::declval>()))> { 78 | static const RawStreamProxy> 79 | printable(const llvm::Optional &V) { 80 | return {V}; 81 | } 82 | }; 83 | } // namespace llvm_gtest 84 | #endif // !GTEST_NO_LLVM_RAW_OSTREAM 85 | 86 | #endif // GTEST_INCLUDE_GTEST_INTERNAL_CUSTOM_RAW_OSTREAM_H_ 87 | -------------------------------------------------------------------------------- /cxx/external/unittest/googletest/include/gtest/internal/gtest-port-arch.h: -------------------------------------------------------------------------------- 1 | // Copyright 2015, Google Inc. 2 | // All rights reserved. 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are 6 | // met: 7 | // 8 | // * Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above 11 | // copyright notice, this list of conditions and the following disclaimer 12 | // in the documentation and/or other materials provided with the 13 | // distribution. 14 | // * Neither the name of Google Inc. nor the names of its 15 | // contributors may be used to endorse or promote products derived from 16 | // this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | // 30 | // The Google C++ Testing Framework (Google Test) 31 | // 32 | // This header file defines the GTEST_OS_* macro. 33 | // It is separate from gtest-port.h so that custom/gtest-port.h can include it. 34 | 35 | #ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_ARCH_H_ 36 | #define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_ARCH_H_ 37 | 38 | // Determines the platform on which Google Test is compiled. 39 | #ifdef __CYGWIN__ 40 | # define GTEST_OS_CYGWIN 1 41 | #elif defined __SYMBIAN32__ 42 | # define GTEST_OS_SYMBIAN 1 43 | #elif defined _WIN32 44 | # define GTEST_OS_WINDOWS 1 45 | # ifdef _WIN32_WCE 46 | # define GTEST_OS_WINDOWS_MOBILE 1 47 | # elif defined(__MINGW__) || defined(__MINGW32__) 48 | # define GTEST_OS_WINDOWS_MINGW 1 49 | # elif defined(WINAPI_FAMILY) 50 | # include 51 | # if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) 52 | # define GTEST_OS_WINDOWS_DESKTOP 1 53 | # elif WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_PHONE_APP) 54 | # define GTEST_OS_WINDOWS_PHONE 1 55 | # elif WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP) 56 | # define GTEST_OS_WINDOWS_RT 1 57 | # else 58 | // WINAPI_FAMILY defined but no known partition matched. 59 | // Default to desktop. 60 | # define GTEST_OS_WINDOWS_DESKTOP 1 61 | # endif 62 | # else 63 | # define GTEST_OS_WINDOWS_DESKTOP 1 64 | # endif // _WIN32_WCE 65 | #elif defined __APPLE__ 66 | # define GTEST_OS_MAC 1 67 | # if TARGET_OS_IPHONE 68 | # define GTEST_OS_IOS 1 69 | # endif 70 | #elif defined __FreeBSD__ 71 | # define GTEST_OS_FREEBSD 1 72 | #elif defined __linux__ 73 | # define GTEST_OS_LINUX 1 74 | # if defined __ANDROID__ 75 | # define GTEST_OS_LINUX_ANDROID 1 76 | # endif 77 | #elif defined __MVS__ 78 | # define GTEST_OS_ZOS 1 79 | #elif defined(__sun) && defined(__SVR4) 80 | # define GTEST_OS_SOLARIS 1 81 | #elif defined(_AIX) 82 | # define GTEST_OS_AIX 1 83 | #elif defined(__hpux) 84 | # define GTEST_OS_HPUX 1 85 | #elif defined __native_client__ 86 | # define GTEST_OS_NACL 1 87 | #elif defined __NetBSD__ 88 | # define GTEST_OS_NETBSD 1 89 | #elif defined __OpenBSD__ 90 | # define GTEST_OS_OPENBSD 1 91 | #elif defined __QNX__ 92 | # define GTEST_OS_QNX 1 93 | #elif defined(__HAIKU__) 94 | # define GTEST_OS_HAIKU 1 95 | #elif defined(_MINIX) 96 | # define GTEST_OS_MINIX 1 97 | #endif // __CYGWIN__ 98 | 99 | #endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_ARCH_H_ 100 | -------------------------------------------------------------------------------- /cxx/external/unittest/googlemock/include/gmock/internal/gmock-port.h: -------------------------------------------------------------------------------- 1 | // Copyright 2008, Google Inc. 2 | // All rights reserved. 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are 6 | // met: 7 | // 8 | // * Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above 11 | // copyright notice, this list of conditions and the following disclaimer 12 | // in the documentation and/or other materials provided with the 13 | // distribution. 14 | // * Neither the name of Google Inc. nor the names of its 15 | // contributors may be used to endorse or promote products derived from 16 | // this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | // 30 | // Author: vadimb@google.com (Vadim Berman) 31 | // 32 | // Low-level types and utilities for porting Google Mock to various 33 | // platforms. All macros ending with _ and symbols defined in an 34 | // internal namespace are subject to change without notice. Code 35 | // outside Google Mock MUST NOT USE THEM DIRECTLY. Macros that don't 36 | // end with _ are part of Google Mock's public API and can be used by 37 | // code outside Google Mock. 38 | 39 | #ifndef GMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_PORT_H_ 40 | #define GMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_PORT_H_ 41 | 42 | #include 43 | #include 44 | #include 45 | 46 | // Most of the utilities needed for porting Google Mock are also 47 | // required for Google Test and are defined in gtest-port.h. 48 | // 49 | // Note to maintainers: to reduce code duplication, prefer adding 50 | // portability utilities to Google Test's gtest-port.h instead of 51 | // here, as Google Mock depends on Google Test. Only add a utility 52 | // here if it's truly specific to Google Mock. 53 | #include "gtest/internal/gtest-linked_ptr.h" 54 | #include "gtest/internal/gtest-port.h" 55 | #include "gmock/internal/custom/gmock-port.h" 56 | 57 | // To avoid conditional compilation everywhere, we make it 58 | // gmock-port.h's responsibility to #include the header implementing 59 | // tr1/tuple. gmock-port.h does this via gtest-port.h, which is 60 | // guaranteed to pull in the tuple header. 61 | 62 | // For MS Visual C++, check the compiler version. At least VS 2003 is 63 | // required to compile Google Mock. 64 | #if defined(_MSC_VER) && _MSC_VER < 1310 65 | # error "At least Visual C++ 2003 (7.1) is required to compile Google Mock." 66 | #endif 67 | 68 | // Macro for referencing flags. This is public as we want the user to 69 | // use this syntax to reference Google Mock flags. 70 | #define GMOCK_FLAG(name) FLAGS_gmock_##name 71 | 72 | #if !defined(GMOCK_DECLARE_bool_) 73 | 74 | // Macros for declaring flags. 75 | #define GMOCK_DECLARE_bool_(name) extern GTEST_API_ bool GMOCK_FLAG(name) 76 | #define GMOCK_DECLARE_int32_(name) \ 77 | extern GTEST_API_ ::testing::internal::Int32 GMOCK_FLAG(name) 78 | #define GMOCK_DECLARE_string_(name) \ 79 | extern GTEST_API_ ::std::string GMOCK_FLAG(name) 80 | 81 | // Macros for defining flags. 82 | #define GMOCK_DEFINE_bool_(name, default_val, doc) \ 83 | GTEST_API_ bool GMOCK_FLAG(name) = (default_val) 84 | #define GMOCK_DEFINE_int32_(name, default_val, doc) \ 85 | GTEST_API_ ::testing::internal::Int32 GMOCK_FLAG(name) = (default_val) 86 | #define GMOCK_DEFINE_string_(name, default_val, doc) \ 87 | GTEST_API_ ::std::string GMOCK_FLAG(name) = (default_val) 88 | 89 | #endif // !defined(GMOCK_DECLARE_bool_) 90 | 91 | #endif // GMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_PORT_H_ 92 | -------------------------------------------------------------------------------- /cxx/external/unittest/googletest/src/gtest-typed-test.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2008 Google Inc. 2 | // All Rights Reserved. 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are 6 | // met: 7 | // 8 | // * Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above 11 | // copyright notice, this list of conditions and the following disclaimer 12 | // in the documentation and/or other materials provided with the 13 | // distribution. 14 | // * Neither the name of Google Inc. nor the names of its 15 | // contributors may be used to endorse or promote products derived from 16 | // this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | // 30 | // Author: wan@google.com (Zhanyong Wan) 31 | 32 | #include "gtest/gtest-typed-test.h" 33 | #include "gtest/gtest.h" 34 | 35 | namespace testing { 36 | namespace internal { 37 | 38 | #if GTEST_HAS_TYPED_TEST_P 39 | 40 | // Skips to the first non-space char in str. Returns an empty string if str 41 | // contains only whitespace characters. 42 | static const char* SkipSpaces(const char* str) { 43 | while (IsSpace(*str)) 44 | str++; 45 | return str; 46 | } 47 | 48 | static std::vector SplitIntoTestNames(const char* src) { 49 | std::vector name_vec; 50 | src = SkipSpaces(src); 51 | for (; src != NULL; src = SkipComma(src)) { 52 | name_vec.push_back(StripTrailingSpaces(GetPrefixUntilComma(src))); 53 | } 54 | return name_vec; 55 | } 56 | 57 | // Verifies that registered_tests match the test names in 58 | // registered_tests_; returns registered_tests if successful, or 59 | // aborts the program otherwise. 60 | const char* TypedTestCasePState::VerifyRegisteredTestNames( 61 | const char* file, int line, const char* registered_tests) { 62 | typedef RegisteredTestsMap::const_iterator RegisteredTestIter; 63 | registered_ = true; 64 | 65 | std::vector name_vec = SplitIntoTestNames(registered_tests); 66 | 67 | Message errors; 68 | 69 | std::set tests; 70 | for (std::vector::const_iterator name_it = name_vec.begin(); 71 | name_it != name_vec.end(); ++name_it) { 72 | const std::string& name = *name_it; 73 | if (tests.count(name) != 0) { 74 | errors << "Test " << name << " is listed more than once.\n"; 75 | continue; 76 | } 77 | 78 | bool found = false; 79 | for (RegisteredTestIter it = registered_tests_.begin(); 80 | it != registered_tests_.end(); 81 | ++it) { 82 | if (name == it->first) { 83 | found = true; 84 | break; 85 | } 86 | } 87 | 88 | if (found) { 89 | tests.insert(name); 90 | } else { 91 | errors << "No test named " << name 92 | << " can be found in this test case.\n"; 93 | } 94 | } 95 | 96 | for (RegisteredTestIter it = registered_tests_.begin(); 97 | it != registered_tests_.end(); 98 | ++it) { 99 | if (tests.count(it->first) == 0) { 100 | errors << "You forgot to list test " << it->first << ".\n"; 101 | } 102 | } 103 | 104 | const std::string& errors_str = errors.GetString(); 105 | if (errors_str != "") { 106 | fprintf(stderr, "%s %s", FormatFileLocation(file, line).c_str(), 107 | errors_str.c_str()); 108 | fflush(stderr); 109 | posix::Abort(); 110 | } 111 | 112 | return registered_tests; 113 | } 114 | 115 | #endif // GTEST_HAS_TYPED_TEST_P 116 | 117 | } // namespace internal 118 | } // namespace testing 119 | -------------------------------------------------------------------------------- /cxx/unittests/Parser/LexerTest.cpp: -------------------------------------------------------------------------------- 1 | #include "s2020/Parser/Lexer.h" 2 | 3 | #include "DiagContext.h" 4 | 5 | #include 6 | 7 | using namespace s2020; 8 | using namespace s2020::parser; 9 | 10 | namespace { 11 | 12 | class LexerTest : public ::testing::Test { 13 | protected: 14 | const llvm::MemoryBuffer &makeBuf(const char *str) { 15 | auto id = context_.sm.addNewSourceBuffer( 16 | llvm::MemoryBuffer::getMemBuffer(str, "input", true)); 17 | return *context_.sm.getSourceBuffer(id); 18 | } 19 | 20 | protected: 21 | ASTContext context_{}; 22 | }; 23 | 24 | TEST_F(LexerTest, SmokeTest) { 25 | Lexer lex{context_, makeBuf(" (+\t #;a 10)\n ")}; 26 | 27 | lex.advance(); 28 | ASSERT_EQ(TokenKind::l_paren, lex.token.getKind()); 29 | lex.advance(); 30 | ASSERT_EQ(TokenKind::identifier, lex.token.getKind()); 31 | lex.advance(); 32 | ASSERT_EQ(TokenKind::datum_comment, lex.token.getKind()); 33 | lex.advance(); 34 | ASSERT_EQ(TokenKind::identifier, lex.token.getKind()); 35 | lex.advance(); 36 | ASSERT_EQ(TokenKind::number, lex.token.getKind()); 37 | ASSERT_TRUE(lex.token.getNumber().exactEquals(10)); 38 | lex.advance(); 39 | ASSERT_EQ(TokenKind::r_paren, lex.token.getKind()); 40 | lex.advance(); 41 | ASSERT_EQ(TokenKind::eof, lex.token.getKind()); 42 | lex.advance(); 43 | ASSERT_EQ(TokenKind::eof, lex.token.getKind()); 44 | 45 | ASSERT_EQ(0, context_.sm.getErrorCount()); 46 | } 47 | 48 | TEST_F(LexerTest, DecimalNumberTest) { 49 | Lexer lex{context_, 50 | makeBuf("1 100 100.5 100e2 0.314e1 314e-2 -1 +20 -50.5 +20.1")}; 51 | 52 | lex.advance(); 53 | ASSERT_EQ(TokenKind::number, lex.token.getKind()); 54 | ASSERT_TRUE(lex.token.getNumber().exactEquals(1)); 55 | 56 | lex.advance(); 57 | ASSERT_EQ(TokenKind::number, lex.token.getKind()); 58 | ASSERT_TRUE(lex.token.getNumber().exactEquals(100)); 59 | 60 | lex.advance(); 61 | ASSERT_EQ(TokenKind::number, lex.token.getKind()); 62 | ASSERT_TRUE(lex.token.getNumber().inexactEquals(100.5)); 63 | 64 | lex.advance(); 65 | ASSERT_EQ(TokenKind::number, lex.token.getKind()); 66 | ASSERT_TRUE(lex.token.getNumber().inexactEquals(100e2)); 67 | 68 | lex.advance(); 69 | ASSERT_EQ(TokenKind::number, lex.token.getKind()); 70 | ASSERT_TRUE(lex.token.getNumber().inexactEquals(3.14)); 71 | 72 | lex.advance(); 73 | ASSERT_EQ(TokenKind::number, lex.token.getKind()); 74 | ASSERT_TRUE(lex.token.getNumber().inexactEquals(3.14)); 75 | 76 | lex.advance(); 77 | ASSERT_EQ(TokenKind::number, lex.token.getKind()); 78 | ASSERT_TRUE(lex.token.getNumber().exactEquals(-1)); 79 | 80 | lex.advance(); 81 | ASSERT_EQ(TokenKind::number, lex.token.getKind()); 82 | ASSERT_TRUE(lex.token.getNumber().exactEquals(20)); 83 | 84 | lex.advance(); 85 | ASSERT_EQ(TokenKind::number, lex.token.getKind()); 86 | ASSERT_TRUE(lex.token.getNumber().inexactEquals(-50.5)); 87 | 88 | lex.advance(); 89 | ASSERT_EQ(TokenKind::number, lex.token.getKind()); 90 | ASSERT_TRUE(lex.token.getNumber().inexactEquals(20.1)); 91 | 92 | lex.advance(); 93 | ASSERT_EQ(TokenKind::eof, lex.token.getKind()); 94 | 95 | ASSERT_EQ(0, context_.sm.getErrorCount()); 96 | } 97 | 98 | TEST_F(LexerTest, BadDecimalNumberTest) { 99 | Lexer lex{context_, makeBuf("1a 1e 123456789123456789001234567890")}; 100 | DiagContext diag{context_.sm}; 101 | 102 | lex.advance(); 103 | ASSERT_EQ(TokenKind::number, lex.token.getKind()); 104 | ASSERT_TRUE(lex.token.getNumber().exactEquals(1)); 105 | ASSERT_EQ(1, diag.getErrCountClear()); 106 | ASSERT_EQ("delimiter expected", diag.getMessage()); 107 | 108 | lex.advance(); 109 | ASSERT_EQ(TokenKind::number, lex.token.getKind()); 110 | ASSERT_TRUE(lex.token.getNumber().inexactEquals(0)); 111 | ASSERT_EQ(1, diag.getErrCountClear()); 112 | ASSERT_EQ("invalid number: missing exponent", diag.getMessage()); 113 | 114 | lex.advance(); 115 | ASSERT_EQ(1, diag.getErrCountClear()); 116 | ASSERT_EQ("number overflows exact range", diag.getMessage()); 117 | 118 | lex.advance(); 119 | ASSERT_EQ(TokenKind::eof, lex.token.getKind()); 120 | ASSERT_EQ(0, diag.getErrCount()); 121 | } 122 | 123 | TEST_F(LexerTest, LineCommentTest) { 124 | Lexer lex{context_, makeBuf("1 ; kjh\n 2 ; 3 4 \r\n 5")}; 125 | 126 | lex.advance(); 127 | ASSERT_TRUE(lex.token.getNumber().exactEquals(1)); 128 | lex.advance(); 129 | ASSERT_TRUE(lex.token.getNumber().exactEquals(2)); 130 | lex.advance(); 131 | ASSERT_TRUE(lex.token.getNumber().exactEquals(5)); 132 | lex.advance(); 133 | ASSERT_EQ(TokenKind::eof, lex.token.getKind()); 134 | } 135 | 136 | } // anonymous namespace -------------------------------------------------------------------------------- /cxx/external/unittest/googletest/src/gtest-test-part.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2008, Google Inc. 2 | // All rights reserved. 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are 6 | // met: 7 | // 8 | // * Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above 11 | // copyright notice, this list of conditions and the following disclaimer 12 | // in the documentation and/or other materials provided with the 13 | // distribution. 14 | // * Neither the name of Google Inc. nor the names of its 15 | // contributors may be used to endorse or promote products derived from 16 | // this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | // 30 | // Author: mheule@google.com (Markus Heule) 31 | // 32 | // The Google C++ Testing Framework (Google Test) 33 | 34 | #include "gtest/gtest-test-part.h" 35 | 36 | // Indicates that this translation unit is part of Google Test's 37 | // implementation. It must come before gtest-internal-inl.h is 38 | // included, or there will be a compiler error. This trick exists to 39 | // prevent the accidental inclusion of gtest-internal-inl.h in the 40 | // user's code. 41 | #define GTEST_IMPLEMENTATION_ 1 42 | #include "src/gtest-internal-inl.h" 43 | #undef GTEST_IMPLEMENTATION_ 44 | 45 | namespace testing { 46 | 47 | using internal::GetUnitTestImpl; 48 | 49 | // Gets the summary of the failure message by omitting the stack trace 50 | // in it. 51 | std::string TestPartResult::ExtractSummary(const char* message) { 52 | const char* const stack_trace = strstr(message, internal::kStackTraceMarker); 53 | return stack_trace == NULL ? message : 54 | std::string(message, stack_trace); 55 | } 56 | 57 | // Prints a TestPartResult object. 58 | std::ostream& operator<<(std::ostream& os, const TestPartResult& result) { 59 | return os 60 | << result.file_name() << ":" << result.line_number() << ": " 61 | << (result.type() == TestPartResult::kSuccess ? "Success" : 62 | result.type() == TestPartResult::kFatalFailure ? "Fatal failure" : 63 | "Non-fatal failure") << ":\n" 64 | << result.message() << std::endl; 65 | } 66 | 67 | // Appends a TestPartResult to the array. 68 | void TestPartResultArray::Append(const TestPartResult& result) { 69 | array_.push_back(result); 70 | } 71 | 72 | // Returns the TestPartResult at the given index (0-based). 73 | const TestPartResult& TestPartResultArray::GetTestPartResult(int index) const { 74 | if (index < 0 || index >= size()) { 75 | printf("\nInvalid index (%d) into TestPartResultArray.\n", index); 76 | internal::posix::Abort(); 77 | } 78 | 79 | return array_[index]; 80 | } 81 | 82 | // Returns the number of TestPartResult objects in the array. 83 | int TestPartResultArray::size() const { 84 | return static_cast(array_.size()); 85 | } 86 | 87 | namespace internal { 88 | 89 | HasNewFatalFailureHelper::HasNewFatalFailureHelper() 90 | : has_new_fatal_failure_(false), 91 | original_reporter_(GetUnitTestImpl()-> 92 | GetTestPartResultReporterForCurrentThread()) { 93 | GetUnitTestImpl()->SetTestPartResultReporterForCurrentThread(this); 94 | } 95 | 96 | HasNewFatalFailureHelper::~HasNewFatalFailureHelper() { 97 | GetUnitTestImpl()->SetTestPartResultReporterForCurrentThread( 98 | original_reporter_); 99 | } 100 | 101 | void HasNewFatalFailureHelper::ReportTestPartResult( 102 | const TestPartResult& result) { 103 | if (result.fatally_failed()) 104 | has_new_fatal_failure_ = true; 105 | original_reporter_->ReportTestPartResult(result); 106 | } 107 | 108 | } // namespace internal 109 | 110 | } // namespace testing 111 | -------------------------------------------------------------------------------- /cxx/include/s2020/Support/CodePointSet.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Facebook, Inc. and its affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #ifndef S2020_PLATFORMUNICODE_CODEPOINTSET_H 9 | #define S2020_PLATFORMUNICODE_CODEPOINTSET_H 10 | 11 | #include 12 | #include 13 | 14 | #include "llvm/ADT/ArrayRef.h" 15 | #include "llvm/ADT/SmallVector.h" 16 | 17 | namespace s2020 { 18 | 19 | /// A simple struct which represents a contiguous range of code points. 20 | struct CodePointRange { 21 | /// The first element of the range. 22 | uint32_t first; 23 | 24 | /// The length of the range. 25 | uint32_t length; 26 | 27 | /// \return one past the last element of the range. 28 | uint32_t end() const { 29 | assert(first + length >= first && "Range overflowed"); 30 | return first + length; 31 | } 32 | 33 | /// \return whether this range overlaps another range. 34 | bool overlaps(const CodePointRange &rhs) { 35 | return this->first < rhs.end() && rhs.first < this->end(); 36 | } 37 | 38 | /// \return whether this range abuts (is exactly next to) another range. 39 | bool abuts(const CodePointRange &rhs) { 40 | return this->first == rhs.end() || rhs.first == this->end(); 41 | } 42 | }; 43 | 44 | /// A class which manages a set of Unicode codepoints as a list of sorted, 45 | /// disjoint ranges. Deletion is not supported. 46 | 47 | // N.B.: This may seem a natural use case for llvm::IntervalMap. However it is 48 | // not for a few reasons: 49 | // 1. IntervalMap trips an assertion if you add a range that overlaps an 50 | // existing range. So when inserting, you must mask out the ranges already 51 | // stored. 52 | // 2. IntervalMap requires an allocator whose lifetime is awkward to manage. 53 | // 3. IntervalMap is quite complex and is significant code size regression 54 | // relative to this. 55 | class CodePointSet { 56 | public: 57 | /// Add a range of code points to this set. 58 | void add(CodePointRange r) { 59 | if (r.length == 0) 60 | return; 61 | 62 | // Use equal_range to find the subarray which we overlap, treating 63 | // overlapping or abutting as equality. 64 | auto cmp = [](CodePointRange lhs, CodePointRange rhs) { 65 | if (lhs.overlaps(rhs) || lhs.abuts(rhs)) 66 | return false; 67 | return lhs.first < rhs.first; 68 | }; 69 | auto pair = std::equal_range(ranges_.begin(), ranges_.end(), r, cmp); 70 | 71 | if (pair.first == pair.second) { 72 | // There was no overlap, just insert. 73 | ranges_.insert(pair.first, r); 74 | } else { 75 | // We overlapped with at least one existing range. Extend the first such 76 | // range with the total overlap, and erase any subsequent overlapping 77 | // ranges. 78 | // The beginning of the merged range is the smaller of the first overlap's 79 | // left, and our range's left. The end of the merged range is the larger 80 | // of the last overlaps's end, and our range's end. 81 | uint32_t start = std::min(r.first, pair.first->first); 82 | uint32_t end = std::max(r.end(), (pair.second - 1)->end()); 83 | *pair.first = CodePointRange{start, end - start}; 84 | ranges_.erase(pair.first + 1, pair.second); 85 | } 86 | } 87 | 88 | /// Add a single code point to this set. 89 | void add(uint32_t cp) { 90 | add(CodePointRange{cp, 1}); 91 | } 92 | 93 | /// \return whether the set is empty. 94 | bool empty() const { 95 | return ranges_.empty(); 96 | } 97 | 98 | /// \return the value of the first code point. 99 | uint32_t first() const { 100 | return ranges_.front().first; 101 | } 102 | 103 | /// \return one past the last code point. 104 | uint32_t end() const { 105 | return ranges_.back().end(); 106 | } 107 | 108 | /// \return the list of ranges. 109 | llvm::ArrayRef ranges() const { 110 | return ranges_; 111 | } 112 | 113 | /// \return whether a code point \p cp is contained within this set. 114 | bool contains(uint32_t cp) const { 115 | auto cmp = [](CodePointRange left, uint32_t cp) { 116 | return left.first + left.length <= cp; 117 | }; 118 | auto where = std::lower_bound(ranges_.begin(), ranges_.end(), cp, cmp); 119 | assert( 120 | (where == ranges_.end() || where->end() > cp) && 121 | "Code point should be inside or before found range"); 122 | return where != ranges_.end() && where->first <= cp; 123 | } 124 | 125 | private: 126 | llvm::SmallVector ranges_; 127 | }; 128 | 129 | } // namespace s2020 130 | 131 | #endif // S2020_PLATFORMUNICODE_CODEPOINTSET_H 132 | -------------------------------------------------------------------------------- /cxx/include/s2020/AST/AST.h: -------------------------------------------------------------------------------- 1 | #ifndef SCHEME2020_AST_H 2 | #define SCHEME2020_AST_H 3 | 4 | #include "s2020/AST/ASTContext.h" 5 | 6 | #include "llvm/ADT/StringRef.h" 7 | #include "llvm/Support/SMLoc.h" 8 | 9 | namespace llvm { 10 | class raw_ostream; 11 | } // namespace llvm 12 | 13 | namespace s2020 { 14 | namespace ast { 15 | 16 | using llvm::SMLoc; 17 | using llvm::SMRange; 18 | 19 | enum class NodeKind : uint8_t { 20 | #define S2020_AST_NODE(name) name, 21 | #include "s2020/AST/NodeKinds.def" 22 | _end, 23 | }; 24 | 25 | llvm::StringRef nodeKindStr(NodeKind kind); 26 | 27 | /// This corresponds to a "datum" returned by the "read" procedure, but we call 28 | /// it an \c ast::Node to avoid confusion between compile time and runtime. Also 29 | /// it is decorated with location information. 30 | class Node { 31 | protected: 32 | explicit Node(NodeKind kind) : kind_(kind) {} 33 | 34 | public: 35 | NodeKind getKind() const { 36 | return kind_; 37 | } 38 | 39 | llvm::StringRef getNodeName() const { 40 | return nodeKindStr(getKind()); 41 | } 42 | 43 | void setSourceRange(SMRange rng) { 44 | sourceRange_ = rng; 45 | } 46 | SMRange getSourceRange() const { 47 | return sourceRange_; 48 | } 49 | void setStartLoc(SMLoc loc) { 50 | sourceRange_.Start = loc; 51 | } 52 | SMLoc getStartLoc() const { 53 | return sourceRange_.Start; 54 | } 55 | void setEndLoc(SMLoc loc) { 56 | sourceRange_.End = loc; 57 | } 58 | SMLoc getEndLoc() const { 59 | return sourceRange_.End; 60 | } 61 | 62 | /// Copy all location data from a different node. 63 | void copyLocationFrom(const Node *src) { 64 | setSourceRange(src->getSourceRange()); 65 | } 66 | 67 | // Allow allocation of AST nodes by using the Context allocator or by a 68 | // placement new. 69 | 70 | void *operator new( 71 | size_t size, 72 | ASTContext &ctx, 73 | size_t alignment = alignof(double)) { 74 | return ctx.allocateNode(size, alignment); 75 | } 76 | void *operator new(size_t, void *mem) { 77 | return mem; 78 | } 79 | 80 | void operator delete(void *, ASTContext &, size_t) {} 81 | void operator delete(void *, size_t) {} 82 | 83 | private: 84 | // Make new/delete illegal for Datum nodes. 85 | 86 | void *operator new(size_t) { 87 | llvm_unreachable("AST nodes cannot be allocated with regular new"); 88 | } 89 | void operator delete(void *) { 90 | llvm_unreachable("AST nodes cannot be released with regular delete"); 91 | } 92 | 93 | private: 94 | NodeKind kind_; 95 | SMRange sourceRange_; 96 | }; 97 | 98 | template 99 | class BaseNode : public Node { 100 | public: 101 | explicit BaseNode() : Node(KIND) {} 102 | 103 | static bool classof(const Node *v) { 104 | return v->getKind() == KIND; 105 | } 106 | }; 107 | 108 | template 109 | class SimpleNode : public BaseNode { 110 | public: 111 | explicit SimpleNode(const V &value) : value_(value) {} 112 | 113 | const V &getValue() const { 114 | return value_; 115 | } 116 | 117 | private: 118 | V value_; 119 | }; 120 | 121 | using BooleanNode = SimpleNode; 122 | using CharacterNode = SimpleNode; 123 | using StringNode = SimpleNode; 124 | using SymbolNode = SimpleNode; 125 | using NumberNode = SimpleNode; 126 | using NullNode = BaseNode; 127 | 128 | // FIXME: implement these. 129 | using BytevectorNode = BaseNode; 130 | using VectorNode = BaseNode; 131 | 132 | class PairNode : public BaseNode { 133 | public: 134 | explicit PairNode(Node *car, Node *cdr) : car_(car), cdr_(cdr) {} 135 | 136 | Node *getCar() const { 137 | return car_; 138 | } 139 | void setCar(Node *car) { 140 | car_ = car; 141 | } 142 | Node *getCdr() const { 143 | return cdr_; 144 | } 145 | void setCdr(Node *cdr) { 146 | cdr_ = cdr; 147 | } 148 | 149 | private: 150 | Node *car_; 151 | Node *cdr_; 152 | }; 153 | 154 | /// Allocate a new PairNode. 155 | PairNode *cons(ASTContext &ctx, Node *a, Node *b); 156 | 157 | // Allocate a new proper list. 158 | inline Node *list(ASTContext &ctx) { 159 | return new (ctx) NullNode(); 160 | } 161 | template 162 | inline Node *list(ASTContext &ctx, Node *first, Args... args) { 163 | return cons(ctx, first, list(ctx, args...)); 164 | } 165 | 166 | /// Compare the two ASTs (ignoring source coordinates). 167 | bool deepEqual(const Node *a, const Node *b); 168 | 169 | /// Print the AST recursively. 170 | void dump(llvm::raw_ostream &OS, const Node *node); 171 | 172 | } // namespace ast 173 | } // namespace s2020 174 | 175 | #endif // SCHEME2020_AST_H 176 | -------------------------------------------------------------------------------- /cxx/include/s2020/Support/StringTable.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Facebook, Inc. and its affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #ifndef S2020_SUPPORT_STRINGTABLE_H 9 | #define S2020_SUPPORT_STRINGTABLE_H 10 | 11 | #include "llvm/ADT/DenseMap.h" 12 | #include "llvm/ADT/StringRef.h" 13 | 14 | namespace llvm { 15 | class raw_ostream; 16 | } // namespace llvm 17 | 18 | namespace s2020 { 19 | 20 | using llvm::StringRef; 21 | 22 | /// Allocate a StringRef with a '\0' following after the end. 23 | template 24 | StringRef zeroTerminate(Allocator &allocator, StringRef str) { 25 | // Allocate a copy of the name, adding a trailing \0 for convenience. 26 | auto *s = allocator.template Allocate(str.size() + 1); 27 | auto end = std::copy(str.begin(), str.end(), s); 28 | *end = 0; // Zero terminate string. 29 | 30 | // NOTE: returning the original size. 31 | return StringRef(s, str.size()); 32 | } 33 | 34 | class UniqueString { 35 | const StringRef str_; 36 | 37 | UniqueString(const UniqueString &) = delete; 38 | UniqueString &operator=(const UniqueString &) = delete; 39 | 40 | public: 41 | explicit UniqueString(StringRef str) : str_(str){}; 42 | 43 | const StringRef &str() const { 44 | return str_; 45 | } 46 | const char *c_str() const { 47 | return str_.begin(); 48 | } 49 | 50 | explicit operator StringRef() const { 51 | return str_; 52 | } 53 | }; 54 | 55 | /// This is an instance of a uniqued identifier created by StringTable. It is 56 | /// just a wrapper around a UniqueString pointer. Identifier is passed by value 57 | /// and must be kept small. 58 | class Identifier { 59 | public: 60 | using PtrType = UniqueString *; 61 | 62 | explicit Identifier() = default; 63 | 64 | private: 65 | PtrType ptr_{nullptr}; 66 | 67 | explicit Identifier(PtrType ptr) : ptr_(ptr) {} 68 | 69 | public: 70 | bool isValid() const { 71 | return ptr_ != nullptr; 72 | } 73 | 74 | /// \returns the pointer value that the context uses to index this string. We 75 | /// Also use this value to hash the identifier. 76 | PtrType getUnderlyingPointer() const { 77 | return ptr_; 78 | } 79 | 80 | static Identifier getFromPointer(UniqueString *ptr) { 81 | return Identifier(ptr); 82 | } 83 | 84 | bool operator==(Identifier RHS) const { 85 | return ptr_ == RHS.ptr_; 86 | } 87 | bool operator!=(Identifier RHS) const { 88 | return !(*this == RHS); 89 | } 90 | 91 | const StringRef &str() const { 92 | return ptr_->str(); 93 | } 94 | const char *c_str() const { 95 | return ptr_->c_str(); 96 | } 97 | }; 98 | 99 | llvm::raw_ostream &operator<<(llvm::raw_ostream &os, Identifier id); 100 | 101 | using llvm::StringRef; 102 | /// Encapsulates a table of unique zero-terminated strings. Unlike 103 | /// llvm::StringMap it gives us access to the string itself and also provides 104 | /// convenient zero termination. 105 | class StringTable { 106 | using Allocator = llvm::BumpPtrAllocator; 107 | Allocator &allocator_; 108 | 109 | llvm::DenseMap strMap_{}; 110 | 111 | StringTable(const StringTable &) = delete; 112 | StringTable &operator=(const StringTable &_) = delete; 113 | 114 | public: 115 | explicit StringTable(Allocator &allocator) : allocator_(allocator){}; 116 | 117 | /// Return a unique zero-terminated copy of the supplied string \p name. 118 | UniqueString *getString(StringRef name) { 119 | // Already in the map? 120 | auto it = strMap_.find(name); 121 | if (it != strMap_.end()) 122 | return it->second; 123 | 124 | // Allocate a zero-terminated copy of the string 125 | auto *str = new (allocator_.Allocate()) 126 | UniqueString(zeroTerminate(allocator_, name)); 127 | strMap_.insert({str->str(), str}); 128 | return str; 129 | } 130 | 131 | /// A wrapper arond getString() returning an Identifier. 132 | Identifier getIdentifier(StringRef name) { 133 | return Identifier::getFromPointer(getString(name)); 134 | } 135 | }; 136 | 137 | } // namespace s2020 138 | 139 | // Enable using Identifier in DenseMap. 140 | namespace llvm { 141 | 142 | template <> 143 | struct DenseMapInfo { 144 | static inline s2020::Identifier getEmptyKey() { 145 | return s2020::Identifier::getFromPointer( 146 | DenseMapInfo::getEmptyKey()); 147 | } 148 | static inline s2020::Identifier getTombstoneKey() { 149 | return s2020::Identifier::getFromPointer( 150 | DenseMapInfo::getTombstoneKey()); 151 | } 152 | static inline unsigned getHashValue(s2020::Identifier id) { 153 | return DenseMapInfo::getHashValue( 154 | id.getUnderlyingPointer()); 155 | } 156 | static inline bool isEqual(s2020::Identifier a, s2020::Identifier b) { 157 | return a == b; 158 | } 159 | }; 160 | 161 | } // namespace llvm 162 | 163 | #endif // S2020_SUPPORT_STRINGTABLE_H 164 | -------------------------------------------------------------------------------- /cxx/lib/Support/UTF8.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Facebook, Inc. and its affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #include "s2020/Support/UTF8.h" 9 | 10 | namespace s2020 { 11 | 12 | void encodeUTF8(char *&dst, uint32_t cp) { 13 | char *d = dst; 14 | if (cp <= 0x7F) { 15 | *d = (char)cp; 16 | ++d; 17 | } else if (cp <= 0x7FF) { 18 | d[1] = (cp & 0x3F) | 0x80; 19 | cp >>= 6; 20 | d[0] = (cp & 0x1F) | 0xC0; 21 | d += 2; 22 | } else if (cp <= 0xFFFF) { 23 | d[2] = (cp & 0x3F) | 0x80; 24 | cp >>= 6; 25 | d[1] = (cp & 0x3F) | 0x80; 26 | cp >>= 6; 27 | d[0] = (cp & 0x0F) | 0xE0; 28 | d += 3; 29 | } else if (cp <= 0x1FFFFF) { 30 | d[3] = (cp & 0x3F) | 0x80; 31 | cp >>= 6; 32 | d[2] = (cp & 0x3F) | 0x80; 33 | cp >>= 6; 34 | d[1] = (cp & 0x3F) | 0x80; 35 | cp >>= 6; 36 | d[0] = (cp & 0x07) | 0xF0; 37 | d += 4; 38 | } else if (cp <= 0x3FFFFFF) { 39 | d[4] = (cp & 0x3F) | 0x80; 40 | cp >>= 6; 41 | d[3] = (cp & 0x3F) | 0x80; 42 | cp >>= 6; 43 | d[2] = (cp & 0x3F) | 0x80; 44 | cp >>= 6; 45 | d[1] = (cp & 0x3F) | 0x80; 46 | cp >>= 6; 47 | d[0] = (cp & 0x03) | 0xF8; 48 | d += 5; 49 | } else { 50 | d[5] = (cp & 0x3F) | 0x80; 51 | cp >>= 6; 52 | d[4] = (cp & 0x3F) | 0x80; 53 | cp >>= 6; 54 | d[3] = (cp & 0x3F) | 0x80; 55 | cp >>= 6; 56 | d[2] = (cp & 0x3F) | 0x80; 57 | cp >>= 6; 58 | d[1] = (cp & 0x3F) | 0x80; 59 | cp >>= 6; 60 | d[0] = (cp & 0x01) | 0xFC; 61 | d += 6; 62 | } 63 | dst = d; 64 | } 65 | 66 | bool convertUTF16ToUTF8WithReplacements( 67 | std::string &out, 68 | llvm::ArrayRef input, 69 | size_t maxCharacters) { 70 | out.clear(); 71 | out.reserve(input.size()); 72 | // Stop early if we've reached currNumCharacters worth of UTF-8 characters. 73 | size_t currNumCharacters = 0; 74 | if (!maxCharacters) { 75 | // Condition checks are easier if this number is set to the max value. 76 | maxCharacters = std::numeric_limits::max(); 77 | } 78 | for (auto cur = input.begin(), end = input.end(); 79 | cur < end && currNumCharacters < maxCharacters; 80 | ++cur, ++currNumCharacters) { 81 | char16_t c = cur[0]; 82 | // ASCII fast-path. 83 | if (LLVM_LIKELY(c <= 0x7F)) { 84 | out.push_back(static_cast(c)); 85 | continue; 86 | } 87 | 88 | char32_t c32; 89 | if (isLowSurrogate(cur[0])) { 90 | // Unpaired low surrogate. 91 | c32 = UNICODE_REPLACEMENT_CHARACTER; 92 | } else if (isHighSurrogate(cur[0])) { 93 | // Leading high surrogate. See if the next character is a low surrogate. 94 | if (cur + 1 == end || !isLowSurrogate(cur[1])) { 95 | // Trailing or unpaired high surrogate. 96 | c32 = UNICODE_REPLACEMENT_CHARACTER; 97 | } else { 98 | // Decode surrogate pair and increment, because we consumed two chars. 99 | c32 = decodeSurrogatePair(cur[0], cur[1]); 100 | ++cur; 101 | } 102 | } else { 103 | // Not a surrogate. 104 | c32 = c; 105 | } 106 | 107 | char buff[UTF8CodepointMaxBytes]; 108 | char *ptr = buff; 109 | encodeUTF8(ptr, c32); 110 | out.insert(out.end(), buff, ptr); 111 | } 112 | return currNumCharacters < maxCharacters; 113 | } 114 | 115 | void convertUTF16ToUTF8WithSingleSurrogates( 116 | std::string &dest, 117 | llvm::ArrayRef input) { 118 | dest.clear(); 119 | dest.reserve(input.size()); 120 | for (char16_t c : input) { 121 | // ASCII fast-path. 122 | if (LLVM_LIKELY(c <= 0x7F)) { 123 | dest.push_back(static_cast(c)); 124 | continue; 125 | } 126 | char32_t c32 = c; 127 | char buff[UTF8CodepointMaxBytes]; 128 | char *ptr = buff; 129 | encodeUTF8(ptr, c32); 130 | dest.insert(dest.end(), buff, ptr); 131 | } 132 | } 133 | 134 | bool isAllASCII(const uint8_t *start, const uint8_t *end) { 135 | const uint8_t *cursor = start; 136 | size_t len = end - start; 137 | static_assert( 138 | sizeof(uint32_t) == 4 && alignof(uint32_t) <= 4, 139 | "uint32_t must be 4 bytes and cannot be more than 4 byte aligned"); 140 | 141 | if (len >= 4) { 142 | // Step by 1s until aligned for uint32_t. 143 | uint8_t mask = 0; 144 | while ((uintptr_t)cursor % alignof(uint32_t)) { 145 | mask |= *cursor++; 146 | len -= 1; 147 | } 148 | if (mask & 0x80u) { 149 | return false; 150 | } 151 | 152 | // Now that we are aligned, step by 4s. 153 | while (len >= 4) { 154 | uint32_t val = *(const uint32_t *)cursor; 155 | if (val & 0x80808080u) { 156 | return false; 157 | } 158 | cursor += 4; 159 | len -= 4; 160 | } 161 | } 162 | assert(len < 4 && "Length should now be less than 4"); 163 | uint8_t mask = 0; 164 | while (len--) { 165 | mask |= *cursor++; 166 | } 167 | if (mask & 0x80u) 168 | return false; 169 | return true; 170 | } 171 | 172 | } // namespace s2020 173 | -------------------------------------------------------------------------------- /cxx/include/s2020/Parser/Lexer.h: -------------------------------------------------------------------------------- 1 | #ifndef SCHEME2020_PARSER_LEXER_H 2 | #define SCHEME2020_PARSER_LEXER_H 3 | 4 | #include "s2020/AST/ASTContext.h" 5 | 6 | namespace s2020 { 7 | namespace parser { 8 | 9 | using ast::ASTContext; 10 | using ast::ExactNumberT; 11 | using ast::InexactNumberT; 12 | using ast::Number; 13 | 14 | enum class TokenKind : uint8_t { 15 | #define TOK(name, str) name, 16 | #include "TokenKinds.def" 17 | _last_token, 18 | }; 19 | 20 | inline constexpr unsigned ord(TokenKind kind) { 21 | return static_cast(kind); 22 | } 23 | 24 | static constexpr unsigned NUM_TOKENS = ord(TokenKind::_last_token); 25 | const char *tokenKindStr(TokenKind kind); 26 | 27 | /// A convenient way to structurally group the data associated with the / last 28 | /// token. More than one instance does not exist in one lexer. 29 | class Token { 30 | friend class Lexer; 31 | 32 | public: 33 | Token(const Token &) = delete; 34 | void operator=(const Token &) = delete; 35 | 36 | Token() {} 37 | ~Token() {} 38 | 39 | TokenKind getKind() const { 40 | return kind_; 41 | } 42 | 43 | SMLoc getStartLoc() const { 44 | return range_.Start; 45 | } 46 | SMLoc getEndLoc() const { 47 | return range_.End; 48 | } 49 | SMRange getSourceRange() const { 50 | return range_; 51 | } 52 | 53 | StringRef inputStr() const { 54 | return StringRef( 55 | range_.Start.getPointer(), 56 | range_.End.getPointer() - range_.Start.getPointer()); 57 | } 58 | 59 | const Number &getNumber() const { 60 | assert(getKind() == TokenKind::number); 61 | return number_; 62 | } 63 | 64 | Identifier getIdentifier() const { 65 | assert(getKind() == TokenKind::identifier); 66 | return ident_; 67 | } 68 | 69 | private: 70 | void setStart(const char *start) { 71 | range_.Start = SMLoc::getFromPointer(start); 72 | } 73 | void setEnd(const char *end) { 74 | range_.End = SMLoc::getFromPointer(end); 75 | } 76 | void setIdentifier(Identifier ident) { 77 | kind_ = TokenKind::identifier; 78 | ident_ = ident; 79 | } 80 | void setNumber(const Number &n) { 81 | kind_ = TokenKind::number; 82 | number_ = n; 83 | } 84 | void setKind(TokenKind kind) { 85 | kind_ = kind; 86 | } 87 | 88 | private: 89 | TokenKind kind_{TokenKind::none}; 90 | SMRange range_{}; 91 | union { 92 | Identifier ident_; 93 | Number number_; 94 | }; 95 | }; 96 | 97 | class Lexer { 98 | public: 99 | /// The last scanned token. 100 | Token token{}; 101 | 102 | explicit Lexer(ASTContext &context, const llvm::MemoryBuffer &input); 103 | ~Lexer(); 104 | 105 | ASTContext &getContext() const { 106 | return context_; 107 | } 108 | 109 | /// Force an EOF at the next token. 110 | void forceEOF() { 111 | curCharPtr_ = bufferEnd_; 112 | } 113 | 114 | /// Consume the current token and scan the next one, which becomes the new 115 | /// current token. 116 | void advance(); 117 | 118 | Identifier getIdentifier(StringRef name) { 119 | return context_.stringTable.getIdentifier(name); 120 | } 121 | 122 | /// Report an error for the range from startLoc to curCharPtr. 123 | bool errorRange(SMLoc startLoc, const llvm::Twine &msg) { 124 | return error({startLoc, SMLoc::getFromPointer(curCharPtr_)}, msg); 125 | } 126 | 127 | /// Report an error using the current token's location. 128 | bool error(const llvm::Twine &msg) { 129 | return error(token.getSourceRange(), msg); 130 | } 131 | 132 | /// Emit an error at the specified source location. If the maximum number of 133 | /// errors has been reached, return false and move the scanning pointer to 134 | /// EOF. 135 | /// \return false if too many errors have been emitted and we need to abort. 136 | bool error(SMLoc loc, const llvm::Twine &msg); 137 | 138 | /// Emit an error at the specified source range. If the maximum number of 139 | /// errors has been reached, return false and move the scanning pointer to 140 | /// EOF. 141 | /// \return false if too many errors have been emitted and we need to abort. 142 | bool error(SMRange range, const llvm::Twine &msg); 143 | 144 | /// Emit an error at the specified source location and range. If the maximum 145 | /// number of errors has been reached, return false and move the scanning 146 | /// pointer to EOF. 147 | /// \return false if too many errors have been emitted and we need to abort. 148 | bool error(SMLoc loc, SMRange range, const llvm::Twine &msg); 149 | 150 | private: 151 | /// The current character is expected to be a delimiter or an EOF. If so, 152 | /// do nothing and return. Otherwise, report an error and skip until a 153 | /// delimiter or EOF. 154 | /// \param errorReported whether an error has already been reported and 155 | /// further errors should be supressed. 156 | inline void skipUntilDelimiter(bool errorReported = false); 157 | 158 | /// The slow path of \c skipUntilDelimiter() 159 | /// \param errorReported whether an error has already been reported and 160 | /// further errors should be supressed. 161 | void _skipUntilDelimiterSlowPath(bool errorReported); 162 | 163 | void skipLineComment(const char *start); 164 | void parseNumberDigits( 165 | const char *start, 166 | llvm::Optional exact, 167 | int radix, 168 | int sign); 169 | 170 | private: 171 | ASTContext &context_; 172 | 173 | const char *bufferStart_{}; 174 | const char *bufferEnd_{}; 175 | const char *curCharPtr_{}; 176 | }; 177 | 178 | } // namespace parser 179 | } // namespace s2020 180 | 181 | #endif // SCHEME2020_PARSER_LEXER_H 182 | -------------------------------------------------------------------------------- /cxx/external/unittest/googlemock/src/gmock-cardinalities.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2007, Google Inc. 2 | // All rights reserved. 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are 6 | // met: 7 | // 8 | // * Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above 11 | // copyright notice, this list of conditions and the following disclaimer 12 | // in the documentation and/or other materials provided with the 13 | // distribution. 14 | // * Neither the name of Google Inc. nor the names of its 15 | // contributors may be used to endorse or promote products derived from 16 | // this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | // 30 | // Author: wan@google.com (Zhanyong Wan) 31 | 32 | // Google Mock - a framework for writing C++ mock classes. 33 | // 34 | // This file implements cardinalities. 35 | 36 | #include "gmock/gmock-cardinalities.h" 37 | 38 | #include 39 | #include // NOLINT 40 | #include 41 | #include 42 | #include "gmock/internal/gmock-internal-utils.h" 43 | #include "gtest/gtest.h" 44 | 45 | namespace testing { 46 | 47 | namespace { 48 | 49 | // Implements the Between(m, n) cardinality. 50 | class BetweenCardinalityImpl : public CardinalityInterface { 51 | public: 52 | BetweenCardinalityImpl(int min, int max) 53 | : min_(min >= 0 ? min : 0), 54 | max_(max >= min_ ? max : min_) { 55 | std::stringstream ss; 56 | if (min < 0) { 57 | ss << "The invocation lower bound must be >= 0, " 58 | << "but is actually " << min << "."; 59 | internal::Expect(false, __FILE__, __LINE__, ss.str()); 60 | } else if (max < 0) { 61 | ss << "The invocation upper bound must be >= 0, " 62 | << "but is actually " << max << "."; 63 | internal::Expect(false, __FILE__, __LINE__, ss.str()); 64 | } else if (min > max) { 65 | ss << "The invocation upper bound (" << max 66 | << ") must be >= the invocation lower bound (" << min 67 | << ")."; 68 | internal::Expect(false, __FILE__, __LINE__, ss.str()); 69 | } 70 | } 71 | 72 | // Conservative estimate on the lower/upper bound of the number of 73 | // calls allowed. 74 | virtual int ConservativeLowerBound() const { return min_; } 75 | virtual int ConservativeUpperBound() const { return max_; } 76 | 77 | virtual bool IsSatisfiedByCallCount(int call_count) const { 78 | return min_ <= call_count && call_count <= max_; 79 | } 80 | 81 | virtual bool IsSaturatedByCallCount(int call_count) const { 82 | return call_count >= max_; 83 | } 84 | 85 | virtual void DescribeTo(::std::ostream* os) const; 86 | 87 | private: 88 | const int min_; 89 | const int max_; 90 | 91 | GTEST_DISALLOW_COPY_AND_ASSIGN_(BetweenCardinalityImpl); 92 | }; 93 | 94 | // Formats "n times" in a human-friendly way. 95 | inline internal::string FormatTimes(int n) { 96 | if (n == 1) { 97 | return "once"; 98 | } else if (n == 2) { 99 | return "twice"; 100 | } else { 101 | std::stringstream ss; 102 | ss << n << " times"; 103 | return ss.str(); 104 | } 105 | } 106 | 107 | // Describes the Between(m, n) cardinality in human-friendly text. 108 | void BetweenCardinalityImpl::DescribeTo(::std::ostream* os) const { 109 | if (min_ == 0) { 110 | if (max_ == 0) { 111 | *os << "never called"; 112 | } else if (max_ == INT_MAX) { 113 | *os << "called any number of times"; 114 | } else { 115 | *os << "called at most " << FormatTimes(max_); 116 | } 117 | } else if (min_ == max_) { 118 | *os << "called " << FormatTimes(min_); 119 | } else if (max_ == INT_MAX) { 120 | *os << "called at least " << FormatTimes(min_); 121 | } else { 122 | // 0 < min_ < max_ < INT_MAX 123 | *os << "called between " << min_ << " and " << max_ << " times"; 124 | } 125 | } 126 | 127 | } // Unnamed namespace 128 | 129 | // Describes the given call count to an ostream. 130 | void Cardinality::DescribeActualCallCountTo(int actual_call_count, 131 | ::std::ostream* os) { 132 | if (actual_call_count > 0) { 133 | *os << "called " << FormatTimes(actual_call_count); 134 | } else { 135 | *os << "never called"; 136 | } 137 | } 138 | 139 | // Creates a cardinality that allows at least n calls. 140 | GTEST_API_ Cardinality AtLeast(int n) { return Between(n, INT_MAX); } 141 | 142 | // Creates a cardinality that allows at most n calls. 143 | GTEST_API_ Cardinality AtMost(int n) { return Between(0, n); } 144 | 145 | // Creates a cardinality that allows any number of calls. 146 | GTEST_API_ Cardinality AnyNumber() { return AtLeast(0); } 147 | 148 | // Creates a cardinality that allows between min and max calls. 149 | GTEST_API_ Cardinality Between(int min, int max) { 150 | return Cardinality(new BetweenCardinalityImpl(min, max)); 151 | } 152 | 153 | // Creates a cardinality that allows exactly n calls. 154 | GTEST_API_ Cardinality Exactly(int n) { return Between(n, n); } 155 | 156 | } // namespace testing 157 | -------------------------------------------------------------------------------- /cxx/lib/AST/AST.cpp: -------------------------------------------------------------------------------- 1 | #include "s2020/AST/AST.h" 2 | 3 | #include "llvm/Support/Format.h" 4 | #include "llvm/Support/raw_ostream.h" 5 | 6 | using llvm::cast; 7 | using llvm::dyn_cast; 8 | using llvm::isa; 9 | 10 | namespace s2020 { 11 | namespace ast { 12 | 13 | llvm::StringRef nodeKindStr(NodeKind kind) { 14 | static const char *names[] = { 15 | #define S2020_AST_NODE(name) #name, 16 | #include "s2020/AST/NodeKinds.def" 17 | }; 18 | 19 | assert(kind < NodeKind::_end && "invalid NodeKind"); 20 | return names[(unsigned)kind]; 21 | } 22 | 23 | PairNode *cons(ASTContext &ctx, Node *a, Node *b) { 24 | return new (ctx) PairNode(a, b); 25 | } 26 | 27 | #define DECLARE_SIMPLE_AST_EQUAL(name) \ 28 | static inline bool equal##name(const name##Node *a, const name##Node *b) { \ 29 | return a->getValue() == b->getValue(); \ 30 | } 31 | #define DECLARE_NOTIMPL_AST_EQUAL(name) \ 32 | static inline bool equal##name(const name##Node *a, const name##Node *b) { \ 33 | llvm_unreachable("equal" #name " not implemented"); \ 34 | return false; \ 35 | } 36 | 37 | DECLARE_SIMPLE_AST_EQUAL(Boolean); 38 | DECLARE_SIMPLE_AST_EQUAL(Character); 39 | DECLARE_SIMPLE_AST_EQUAL(String); 40 | DECLARE_SIMPLE_AST_EQUAL(Symbol); 41 | DECLARE_SIMPLE_AST_EQUAL(Number); 42 | 43 | DECLARE_NOTIMPL_AST_EQUAL(Bytevector); 44 | DECLARE_NOTIMPL_AST_EQUAL(Vector); 45 | 46 | static inline bool equalNull(const NullNode *a, const NullNode *b) { 47 | return true; 48 | } 49 | static inline bool equalPair(const PairNode *a, const PairNode *b) { 50 | return deepEqual(a->getCar(), b->getCar()) && 51 | deepEqual(a->getCdr(), b->getCdr()); 52 | } 53 | 54 | bool deepEqual(const Node *a, const Node *b) { 55 | if (a->getKind() != b->getKind()) 56 | return false; 57 | 58 | switch (a->getKind()) { 59 | #define S2020_AST_NODE(name) \ 60 | case NodeKind::name: \ 61 | return equal##name(cast(a), cast(b)); 62 | #include "s2020/AST/NodeKinds.def" 63 | default: 64 | return true; 65 | } 66 | } 67 | 68 | static void dump(llvm::raw_ostream &OS, const Node *node, unsigned indent); 69 | 70 | static void 71 | dumpCharacter(llvm::raw_ostream &OS, const CharacterNode *node, unsigned) { 72 | char32_t ch = cast(node)->getValue(); 73 | OS << "#\\"; 74 | 75 | // Try the named ones first. 76 | switch (ch) { 77 | #define S2020_CHARACTER(name, code) \ 78 | case code: \ 79 | OS << #name; \ 80 | break; 81 | #include "s2020/AST/Characters.def" 82 | default: 83 | if (ch > 32 && ch < 127) 84 | OS.write((unsigned char)ch); 85 | else 86 | OS << llvm::format("0x%x", ch); 87 | break; 88 | } 89 | } 90 | 91 | static void 92 | dumpSymbol(llvm::raw_ostream &OS, const SymbolNode *node, unsigned) { 93 | // TODO: utf-8 94 | llvm::StringRef str = node->getValue().str(); 95 | // Do we need to escape it? 96 | bool escaping = false; 97 | for (auto c : str) { 98 | // FIXME: we should actually enforce the rules for identifiers here. 99 | if (c <= 32 || c >= 127 || c == '|' || c == '\\') { 100 | escaping = true; 101 | break; 102 | } 103 | } 104 | if (escaping) { 105 | OS.write('|'); 106 | for (auto c : str) { 107 | switch (c) { 108 | case '\a': 109 | OS << "\\a"; 110 | break; 111 | case '\b': 112 | OS << "\\b"; 113 | break; 114 | case '\t': 115 | OS << "\\t"; 116 | break; 117 | case '\n': 118 | OS << "\\n"; 119 | break; 120 | case '\r': 121 | OS << "\\r"; 122 | break; 123 | case '|': 124 | OS << "\\|"; 125 | break; 126 | case '\\': 127 | OS << "\\\\"; 128 | break; 129 | default: 130 | if (c >= 32 && c < 127) 131 | OS.write((unsigned char)c); 132 | else 133 | OS << llvm::format("0x%x;", c); 134 | break; 135 | } 136 | } 137 | OS.write('|'); 138 | } else { 139 | OS << str; 140 | } 141 | } 142 | 143 | static void dumpIndent(llvm::raw_ostream &OS, unsigned indent) { 144 | OS << llvm::left_justify("", indent * 4); 145 | } 146 | 147 | static void 148 | dumpPair(llvm::raw_ostream &OS, const PairNode *node, unsigned indent) { 149 | OS << "("; 150 | dump(OS, node->getCar(), indent + 1); 151 | 152 | while (auto *next = dyn_cast(node->getCdr())) { 153 | node = next; 154 | OS << "\n"; 155 | dumpIndent(OS, indent + 1); 156 | dump(OS, node->getCar(), indent + 1); 157 | } 158 | 159 | if (!isa(node->getCdr())) { 160 | OS << " . "; 161 | dump(OS, node->getCdr(), indent + 1); 162 | } 163 | 164 | OS << ")"; 165 | } 166 | 167 | static void 168 | dumpBoolean(llvm::raw_ostream &OS, const BooleanNode *node, unsigned) { 169 | OS << (node->getValue() ? "#t" : "#f"); 170 | } 171 | static void 172 | dumpNumber(llvm::raw_ostream &OS, const NumberNode *node, unsigned) { 173 | OS << node->getValue(); 174 | } 175 | static void 176 | dumpString(llvm::raw_ostream &OS, const StringNode *node, unsigned) { 177 | // TODO: utf-8 178 | OS.write('"'); 179 | OS.write_escaped(node->getValue().str(), true); 180 | OS.write('"'); 181 | } 182 | static void 183 | dumpBytevector(llvm::raw_ostream &OS, const BytevectorNode *node, unsigned) { 184 | llvm_unreachable("not implemented"); 185 | } 186 | static void 187 | dumpVector(llvm::raw_ostream &OS, const VectorNode *node, unsigned) { 188 | llvm_unreachable("not implemented"); 189 | } 190 | static void dumpNull(llvm::raw_ostream &OS, const NullNode *, unsigned) { 191 | OS << "()"; 192 | } 193 | 194 | static void dump(llvm::raw_ostream &OS, const Node *node, unsigned indent) { 195 | switch (node->getKind()) { 196 | #define S2020_AST_NODE(name) \ 197 | case NodeKind::name: \ 198 | dump##name(OS, cast(node), indent); \ 199 | break; 200 | #include "s2020/AST/NodeKinds.def" 201 | default: 202 | break; 203 | } 204 | } 205 | 206 | void dump(llvm::raw_ostream &OS, const Node *node) { 207 | dump(OS, node, 0); 208 | OS << "\n"; 209 | } 210 | 211 | } // namespace ast 212 | } // namespace s2020 -------------------------------------------------------------------------------- /cxx/external/unittest/googlemock/include/gmock/gmock-cardinalities.h: -------------------------------------------------------------------------------- 1 | // Copyright 2007, Google Inc. 2 | // All rights reserved. 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are 6 | // met: 7 | // 8 | // * Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above 11 | // copyright notice, this list of conditions and the following disclaimer 12 | // in the documentation and/or other materials provided with the 13 | // distribution. 14 | // * Neither the name of Google Inc. nor the names of its 15 | // contributors may be used to endorse or promote products derived from 16 | // this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | // 30 | // Author: wan@google.com (Zhanyong Wan) 31 | 32 | // Google Mock - a framework for writing C++ mock classes. 33 | // 34 | // This file implements some commonly used cardinalities. More 35 | // cardinalities can be defined by the user implementing the 36 | // CardinalityInterface interface if necessary. 37 | 38 | #ifndef GMOCK_INCLUDE_GMOCK_GMOCK_CARDINALITIES_H_ 39 | #define GMOCK_INCLUDE_GMOCK_GMOCK_CARDINALITIES_H_ 40 | 41 | #include 42 | #include // NOLINT 43 | #include "gmock/internal/gmock-port.h" 44 | #include "gtest/gtest.h" 45 | 46 | namespace testing { 47 | 48 | // To implement a cardinality Foo, define: 49 | // 1. a class FooCardinality that implements the 50 | // CardinalityInterface interface, and 51 | // 2. a factory function that creates a Cardinality object from a 52 | // const FooCardinality*. 53 | // 54 | // The two-level delegation design follows that of Matcher, providing 55 | // consistency for extension developers. It also eases ownership 56 | // management as Cardinality objects can now be copied like plain values. 57 | 58 | // The implementation of a cardinality. 59 | class CardinalityInterface { 60 | public: 61 | virtual ~CardinalityInterface() {} 62 | 63 | // Conservative estimate on the lower/upper bound of the number of 64 | // calls allowed. 65 | virtual int ConservativeLowerBound() const { return 0; } 66 | virtual int ConservativeUpperBound() const { return INT_MAX; } 67 | 68 | // Returns true iff call_count calls will satisfy this cardinality. 69 | virtual bool IsSatisfiedByCallCount(int call_count) const = 0; 70 | 71 | // Returns true iff call_count calls will saturate this cardinality. 72 | virtual bool IsSaturatedByCallCount(int call_count) const = 0; 73 | 74 | // Describes self to an ostream. 75 | virtual void DescribeTo(::std::ostream* os) const = 0; 76 | }; 77 | 78 | // A Cardinality is a copyable and IMMUTABLE (except by assignment) 79 | // object that specifies how many times a mock function is expected to 80 | // be called. The implementation of Cardinality is just a linked_ptr 81 | // to const CardinalityInterface, so copying is fairly cheap. 82 | // Don't inherit from Cardinality! 83 | class GTEST_API_ Cardinality { 84 | public: 85 | // Constructs a null cardinality. Needed for storing Cardinality 86 | // objects in STL containers. 87 | Cardinality() {} 88 | 89 | // Constructs a Cardinality from its implementation. 90 | explicit Cardinality(const CardinalityInterface* impl) : impl_(impl) {} 91 | 92 | // Conservative estimate on the lower/upper bound of the number of 93 | // calls allowed. 94 | int ConservativeLowerBound() const { return impl_->ConservativeLowerBound(); } 95 | int ConservativeUpperBound() const { return impl_->ConservativeUpperBound(); } 96 | 97 | // Returns true iff call_count calls will satisfy this cardinality. 98 | bool IsSatisfiedByCallCount(int call_count) const { 99 | return impl_->IsSatisfiedByCallCount(call_count); 100 | } 101 | 102 | // Returns true iff call_count calls will saturate this cardinality. 103 | bool IsSaturatedByCallCount(int call_count) const { 104 | return impl_->IsSaturatedByCallCount(call_count); 105 | } 106 | 107 | // Returns true iff call_count calls will over-saturate this 108 | // cardinality, i.e. exceed the maximum number of allowed calls. 109 | bool IsOverSaturatedByCallCount(int call_count) const { 110 | return impl_->IsSaturatedByCallCount(call_count) && 111 | !impl_->IsSatisfiedByCallCount(call_count); 112 | } 113 | 114 | // Describes self to an ostream 115 | void DescribeTo(::std::ostream* os) const { impl_->DescribeTo(os); } 116 | 117 | // Describes the given actual call count to an ostream. 118 | static void DescribeActualCallCountTo(int actual_call_count, 119 | ::std::ostream* os); 120 | 121 | private: 122 | internal::linked_ptr impl_; 123 | }; 124 | 125 | // Creates a cardinality that allows at least n calls. 126 | GTEST_API_ Cardinality AtLeast(int n); 127 | 128 | // Creates a cardinality that allows at most n calls. 129 | GTEST_API_ Cardinality AtMost(int n); 130 | 131 | // Creates a cardinality that allows any number of calls. 132 | GTEST_API_ Cardinality AnyNumber(); 133 | 134 | // Creates a cardinality that allows between min and max calls. 135 | GTEST_API_ Cardinality Between(int min, int max); 136 | 137 | // Creates a cardinality that allows exactly n calls. 138 | GTEST_API_ Cardinality Exactly(int n); 139 | 140 | // Creates a cardinality from its implementation. 141 | inline Cardinality MakeCardinality(const CardinalityInterface* c) { 142 | return Cardinality(c); 143 | } 144 | 145 | } // namespace testing 146 | 147 | #endif // GMOCK_INCLUDE_GMOCK_GMOCK_CARDINALITIES_H_ 148 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Scheme 2020 2 | 3 | Scheme 2020 is intended to be a native compiler for the Scheme programming language, [R7RS-small](https://small.r7rs.org/). The goal is to complete a fully functional implementation in 48 working hours (or six work days). 4 | 5 | An up to date time log is provided in [log.md](log.md). 6 | 7 | Note 1: The number 48 is inspired by the great [Scheme48](http://s48.org/), which was famously implemented in [48 astronomical hours](http://mumble.net/~jar/s48/). 8 | 9 | Note 2: The name "Scheme 2020" was picked after a quick poll of my friends, who were given two options: "QD Scheme" (from quick & dirty) and "Scheme 2020" (because I am doing this in 2020). 10 | 11 | ## Introduction 12 | 13 | I have always loved Scheme for its simplicity and elegance, and always wanted to implement a Scheme compiler. I made a couple of hobby attempts through the years, but somehow never got around to actually completing one (I guess that is not atypical for hobby projects). 14 | 15 | Thinking back, these are common pitfalls: 16 | - My plans were too ambitious and not very incremental. 17 | - I didn't really know what I was doing. 18 | - I chose the wrong toolset. 19 | 20 | The first one is certainly the most important. I believe that for almost any programming project project to be successful, it needs to be operational as soon as possible, and it needs to be kept operational in small and manageable increments. I also believe that good software engineering is frequently about making the right compromises at the right time. 21 | 22 | So, in this project I have decided to force the issue by giving myself a very short and public deadline. Such a short deadline really gives one only very few options of achieving the goal, almost eliminating distractions and scope creep. 23 | 24 | One immediate outcome of the deadline is that I have decided to use C++ as an implementation language instead of Scheme. While in some ways this is very disappointing (what can be cooler than a self-hosting compiler), it is the only realistic option for me, since I haven't actually written anything substantial in Scheme, and it would take more than 48 hours to get up to speed. 25 | 26 | If this works out, I would love to eventually rewrite the compiler in Scheme, so it can become self-hosting. This is not as crazy as it sounds, because not a lot of code can be written in 48 hours, so it should be similarly easy to rewrite. Plus, there would be a very convenient performance benchmark. 27 | 28 | > Note: If I had decided to use Scheme (which I seriously considered), I would have used [Chicken Scheme](https://www.call-cc.org/). Why? Because its minimalistic approach appeals to me, not to mention [Cheney on the M.T.A.](http://home.pipeline.com/~hbaker1/CheneyMTA.html) which is possibly one of the coolest implementation techniques ever. 29 | 30 | ## Implementation 31 | 32 | While I think I have planned the implementation in sufficient detail in my head, most of this section will likely be completed after the end of the 48 hours. 33 | 34 | ### Call/cc 35 | 36 | `call/cc` presents one of the most crucial design decisions in a Scheme implementation because it affects most aspects of code generation and the runtime in pretty fundamental ways. An implementation could not really be said to be "true" Scheme without `call/cc` (which is not to say that it couldn't still be great or very useful). As such, `call/cc` is included in this project's commitment to a "fully functional Scheme in 48 working hours". 37 | 38 | There are at least several well known ways of implementing `call/cc` in order of increasing complexity (this list is not meant to be exclusive): 39 | 1. Converting to continuation-passing-style (CPS). 40 | 2. Heap-allocated activation records. 41 | 3. Boxed mutable variables and stack copying (described in R. Kent Dybvig's dissertation). 42 | 43 | All of the above are all well understood and relatively simple. While very elegant and interesting in the academic sense, these approaches result in code which is not optimal for modern optimization frameworks (like LLVM) or modern CPUs. For example, 1) and 2) defeat CPU return address prediction. These approaches also result in counter-intuitive performance, because of unexpected heap allocations and local variables living in the heap. Debugging is also unlike "regular" imperative languages. 44 | 45 | All of this makes a canonical implementation of `call/cc` somewhat un-attractive. However, the fact remains that a serious Scheme implementation must support it. So, what is the plan? 46 | 47 | Given the deliberately short time frame, the initial version of Scheme2020 has no choice but utilize approach 2). However, afterwards, when there is more time to experiment, I would like to transition to a different model: 48 | - By default continuations will be single shot and *escaping*. This would be sufficient to implement co-routines, for example. 49 | - Multi-shot escaping continuations will be supported via compiler option by CPS conversion. 50 | 51 | > NOTE: in comparison, `setjmp()/longjmp()` or C++ exceptions can be said to be single-shot non-escaping continuations. 52 | 53 | With this strategy, I believe Scheme2020 can eventually feel and perform very natural in an ecosystem of C/C++/Rust, etc, while preserving all of its expressivity and power. 54 | 55 | ### Numeric Tower 56 | 57 | Traditionally Scheme implementations support the following number types: 58 | - exact bigint 59 | - exact rational (a ratio of bigints) 60 | - inexact real (usually IEEE-754) 61 | - complex with any of the above components 62 | 63 | From an implementation viewpoint this is not terribly interesting, as it is all done in library calls. Good implementations usually support some kind of efficient "small int" which automatically overflows into a heap-allocated *bigint*. The techniques for that are well known. 64 | 65 | It is important to note that the R7RS-Small does not require implementations to support all of the above number types. The spec is pretty liberal in this respect and pretty much the only requirement is that an implementation must support separate *exact* and *inexact* number types. The behavior on overlow is not specified. This allows compliant Scheme implementations to exist with de-facto C number semantics. 66 | 67 | Scheme2020 will initially support two number types: 68 | - IEEE 64-bit double 69 | - 64-bit twos complement signed integer, with Java-like semantics (overflow wraps around). 70 | 71 | As far as I can tell, this satisfies the requirements of the spec. More number types can be added incrementally if needed (rationals, complex). I do not plan on adding bigint support because philosophically it takes the implementation in a different direction (not a bad one, just one that I am not personally interested in). 72 | -------------------------------------------------------------------------------- /cxx/lib/Parser/DatumParser.cpp: -------------------------------------------------------------------------------- 1 | #include "s2020/Parser/DatumParser.h" 2 | 3 | #include "s2020/Parser/Lexer.h" 4 | 5 | using llvm::cast; 6 | 7 | namespace s2020 { 8 | namespace parser { 9 | 10 | namespace { 11 | 12 | class DatumParser { 13 | public: 14 | explicit DatumParser( 15 | ast::ASTContext &context, 16 | const llvm::MemoryBuffer &input) 17 | : context_(context), lex_(context, input) { 18 | lex_.advance(); 19 | } 20 | 21 | llvm::Optional> parse(); 22 | 23 | private: 24 | ast::Node *parseDatum(); 25 | 26 | /// Skip all datum comments and return true if there is a fatal error. 27 | bool skipDatumComments(); 28 | 29 | template 30 | ast::Node *makeSimpleNodeAndAdvance(const V &v) { 31 | auto *node = new (context_) N(v); 32 | node->setSourceRange(lex_.token.getSourceRange()); 33 | lex_.advance(); 34 | return node; 35 | } 36 | 37 | ast::Node *parseList(TokenKind closingKind); 38 | 39 | private: 40 | ast::ASTContext &context_; 41 | /// Lex lexer. 42 | Lexer lex_; 43 | /// Whether a fatal error has already been reported, so we shouldn't report 44 | /// any more. 45 | bool fatal_ = false; 46 | /// Maximum allowed nesting level to avoid stack overflow. 47 | static constexpr unsigned MAX_NESTING = 1024; 48 | /// Nesting level. 49 | unsigned nesting_ = 0; 50 | 51 | /// A RAII to maintain the nesting. 52 | class NestingRAII; 53 | }; 54 | 55 | class DatumParser::NestingRAII { 56 | public: 57 | explicit NestingRAII(DatumParser &parser) : p_(parser) { 58 | ++p_.nesting_; 59 | } 60 | ~NestingRAII() { 61 | --p_.nesting_; 62 | } 63 | 64 | private: 65 | DatumParser &p_; 66 | }; 67 | 68 | #define CHECK_NESTING() \ 69 | NestingRAII nestingRAII{*this}; \ 70 | if (nesting_ >= MAX_NESTING) { \ 71 | lex_.error("too many nested expressions"); \ 72 | fatal_ = true; \ 73 | return nullptr; \ 74 | } else { \ 75 | } 76 | 77 | llvm::Optional> DatumParser::parse() { 78 | // Remember how many errors we started with. 79 | if (context_.sm.isErrorLimitReached()) 80 | return llvm::None; 81 | 82 | auto numErrors = context_.sm.getErrorCount(); 83 | 84 | std::vector res{}; 85 | while (auto *datum = parseDatum()) 86 | res.push_back(datum); 87 | 88 | // If errors occurred 89 | if (numErrors != context_.sm.getErrorCount()) 90 | return llvm::None; 91 | 92 | return std::move(res); 93 | } 94 | 95 | ast::Node *DatumParser::parseDatum() { 96 | CHECK_NESTING(); 97 | 98 | for (;;) { 99 | switch (lex_.token.getKind()) { 100 | case TokenKind::eof: 101 | return nullptr; 102 | 103 | case TokenKind::datum_comment: 104 | lex_.advance(); 105 | // Ignore the next datum. 106 | if (!parseDatum()) 107 | return nullptr; 108 | continue; 109 | 110 | case TokenKind::number: 111 | return makeSimpleNodeAndAdvance( 112 | lex_.token.getNumber()); 113 | case TokenKind::identifier: 114 | return makeSimpleNodeAndAdvance( 115 | lex_.token.getIdentifier()); 116 | 117 | case TokenKind::l_paren: 118 | return parseList(TokenKind::r_paren); 119 | case TokenKind::l_square: 120 | return parseList(TokenKind::r_square); 121 | 122 | default: 123 | lex_.error("unexpected token"); 124 | lex_.advance(); 125 | continue; 126 | } 127 | } 128 | } 129 | 130 | bool DatumParser::skipDatumComments() { 131 | while (lex_.token.getKind() == TokenKind::datum_comment) { 132 | lex_.advance(); 133 | if (!parseDatum()) 134 | return fatal_; 135 | } 136 | 137 | return false; 138 | } 139 | 140 | ast::Node *DatumParser::parseList(s2020::parser::TokenKind closingKind) { 141 | CHECK_NESTING(); 142 | 143 | auto startLoc = lex_.token.getStartLoc(); 144 | lex_.advance(); 145 | 146 | if (lex_.token.getKind() == closingKind) { 147 | auto *empty = new (context_.allocateNode()) ast::NullNode(); 148 | empty->setStartLoc(startLoc); 149 | empty->setEndLoc(lex_.token.getEndLoc()); 150 | lex_.advance(); 151 | return empty; 152 | } 153 | 154 | ast::PairNode *head = nullptr; 155 | ast::PairNode *tail = nullptr; 156 | bool dotted = false; 157 | 158 | auto *datum = parseDatum(); 159 | if (!datum) 160 | goto reportUnterminated; 161 | 162 | head = new (context_.allocateNode()) 163 | ast::PairNode(datum, nullptr); 164 | head->setStartLoc(startLoc); 165 | tail = head; 166 | 167 | if (skipDatumComments()) 168 | return nullptr; 169 | 170 | while (lex_.token.getKind() != closingKind) { 171 | if (lex_.token.getKind() == TokenKind::period) { 172 | dotted = true; 173 | 174 | lex_.advance(); 175 | datum = parseDatum(); 176 | if (!datum) 177 | goto reportUnterminated; 178 | 179 | tail->setCdr(datum); 180 | 181 | if (skipDatumComments()) 182 | return nullptr; 183 | 184 | if (lex_.token.getKind() != closingKind) { 185 | lex_.error("list terminator expected"); 186 | context_.sm.note(startLoc, "list started here"); 187 | // Skip until the end of the list. 188 | while (lex_.token.getKind() != TokenKind::eof && 189 | lex_.token.getKind() != closingKind) { 190 | if (!parseDatum()) 191 | return nullptr; 192 | } 193 | } 194 | break; 195 | } 196 | 197 | datum = parseDatum(); 198 | if (!datum) 199 | goto reportUnterminated; 200 | 201 | auto *newTail = new (context_.allocateNode()) 202 | ast::PairNode(datum, nullptr); 203 | newTail->setStartLoc(datum->getStartLoc()); 204 | tail->setCdr(newTail); 205 | tail = newTail; 206 | 207 | if (skipDatumComments()) 208 | return nullptr; 209 | } 210 | 211 | // If this wasn't a dotted list, we must allocate the terminating Null node. 212 | if (!dotted) { 213 | auto *empty = new (context_.allocateNode()) ast::NullNode(); 214 | empty->setSourceRange(lex_.token.getSourceRange()); 215 | tail->setCdr(empty); 216 | } 217 | 218 | // Now that we have reached the end of the list, set all end locations. 219 | for (auto *cur = head;; cur = cast(cur->getCdr())) { 220 | cur->setEndLoc(lex_.token.getEndLoc()); 221 | if (cur == tail) 222 | break; 223 | } 224 | 225 | lex_.advance(); 226 | return head; 227 | 228 | reportUnterminated: 229 | if (!fatal_) { 230 | fatal_ = true; 231 | lex_.error("unterminated list"); 232 | context_.sm.note(startLoc, "list started here"); 233 | } 234 | return nullptr; 235 | } 236 | 237 | } // anonymous namespace 238 | 239 | llvm::Optional> parseDatums( 240 | ast::ASTContext &context, 241 | const llvm::MemoryBuffer &input) { 242 | DatumParser parser{context, input}; 243 | return parser.parse(); 244 | } 245 | 246 | } // namespace parser 247 | } // namespace s2020 -------------------------------------------------------------------------------- /cxx/external/unittest/googletest/include/gtest/gtest-test-part.h: -------------------------------------------------------------------------------- 1 | // Copyright 2008, Google Inc. 2 | // All rights reserved. 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are 6 | // met: 7 | // 8 | // * Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above 11 | // copyright notice, this list of conditions and the following disclaimer 12 | // in the documentation and/or other materials provided with the 13 | // distribution. 14 | // * Neither the name of Google Inc. nor the names of its 15 | // contributors may be used to endorse or promote products derived from 16 | // this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | // 30 | // Author: mheule@google.com (Markus Heule) 31 | // 32 | 33 | #ifndef GTEST_INCLUDE_GTEST_GTEST_TEST_PART_H_ 34 | #define GTEST_INCLUDE_GTEST_GTEST_TEST_PART_H_ 35 | 36 | #include 37 | #include 38 | #include "gtest/internal/gtest-internal.h" 39 | #include "gtest/internal/gtest-string.h" 40 | 41 | namespace testing { 42 | 43 | // A copyable object representing the result of a test part (i.e. an 44 | // assertion or an explicit FAIL(), ADD_FAILURE(), or SUCCESS()). 45 | // 46 | // Don't inherit from TestPartResult as its destructor is not virtual. 47 | class GTEST_API_ TestPartResult { 48 | public: 49 | // The possible outcomes of a test part (i.e. an assertion or an 50 | // explicit SUCCEED(), FAIL(), or ADD_FAILURE()). 51 | enum Type { 52 | kSuccess, // Succeeded. 53 | kNonFatalFailure, // Failed but the test can continue. 54 | kFatalFailure // Failed and the test should be terminated. 55 | }; 56 | 57 | // C'tor. TestPartResult does NOT have a default constructor. 58 | // Always use this constructor (with parameters) to create a 59 | // TestPartResult object. 60 | TestPartResult(Type a_type, 61 | const char* a_file_name, 62 | int a_line_number, 63 | const char* a_message) 64 | : type_(a_type), 65 | file_name_(a_file_name == NULL ? "" : a_file_name), 66 | line_number_(a_line_number), 67 | summary_(ExtractSummary(a_message)), 68 | message_(a_message) { 69 | } 70 | 71 | // Gets the outcome of the test part. 72 | Type type() const { return type_; } 73 | 74 | // Gets the name of the source file where the test part took place, or 75 | // NULL if it's unknown. 76 | const char* file_name() const { 77 | return file_name_.empty() ? NULL : file_name_.c_str(); 78 | } 79 | 80 | // Gets the line in the source file where the test part took place, 81 | // or -1 if it's unknown. 82 | int line_number() const { return line_number_; } 83 | 84 | // Gets the summary of the failure message. 85 | const char* summary() const { return summary_.c_str(); } 86 | 87 | // Gets the message associated with the test part. 88 | const char* message() const { return message_.c_str(); } 89 | 90 | // Returns true iff the test part passed. 91 | bool passed() const { return type_ == kSuccess; } 92 | 93 | // Returns true iff the test part failed. 94 | bool failed() const { return type_ != kSuccess; } 95 | 96 | // Returns true iff the test part non-fatally failed. 97 | bool nonfatally_failed() const { return type_ == kNonFatalFailure; } 98 | 99 | // Returns true iff the test part fatally failed. 100 | bool fatally_failed() const { return type_ == kFatalFailure; } 101 | 102 | private: 103 | Type type_; 104 | 105 | // Gets the summary of the failure message by omitting the stack 106 | // trace in it. 107 | static std::string ExtractSummary(const char* message); 108 | 109 | // The name of the source file where the test part took place, or 110 | // "" if the source file is unknown. 111 | std::string file_name_; 112 | // The line in the source file where the test part took place, or -1 113 | // if the line number is unknown. 114 | int line_number_; 115 | std::string summary_; // The test failure summary. 116 | std::string message_; // The test failure message. 117 | }; 118 | 119 | // Prints a TestPartResult object. 120 | std::ostream& operator<<(std::ostream& os, const TestPartResult& result); 121 | 122 | // An array of TestPartResult objects. 123 | // 124 | // Don't inherit from TestPartResultArray as its destructor is not 125 | // virtual. 126 | class GTEST_API_ TestPartResultArray { 127 | public: 128 | TestPartResultArray() {} 129 | 130 | // Appends the given TestPartResult to the array. 131 | void Append(const TestPartResult& result); 132 | 133 | // Returns the TestPartResult at the given index (0-based). 134 | const TestPartResult& GetTestPartResult(int index) const; 135 | 136 | // Returns the number of TestPartResult objects in the array. 137 | int size() const; 138 | 139 | private: 140 | std::vector array_; 141 | 142 | GTEST_DISALLOW_COPY_AND_ASSIGN_(TestPartResultArray); 143 | }; 144 | 145 | // This interface knows how to report a test part result. 146 | class TestPartResultReporterInterface { 147 | public: 148 | virtual ~TestPartResultReporterInterface() {} 149 | 150 | virtual void ReportTestPartResult(const TestPartResult& result) = 0; 151 | }; 152 | 153 | namespace internal { 154 | 155 | // This helper class is used by {ASSERT|EXPECT}_NO_FATAL_FAILURE to check if a 156 | // statement generates new fatal failures. To do so it registers itself as the 157 | // current test part result reporter. Besides checking if fatal failures were 158 | // reported, it only delegates the reporting to the former result reporter. 159 | // The original result reporter is restored in the destructor. 160 | // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. 161 | class GTEST_API_ HasNewFatalFailureHelper 162 | : public TestPartResultReporterInterface { 163 | public: 164 | HasNewFatalFailureHelper(); 165 | virtual ~HasNewFatalFailureHelper(); 166 | virtual void ReportTestPartResult(const TestPartResult& result); 167 | bool has_new_fatal_failure() const { return has_new_fatal_failure_; } 168 | private: 169 | bool has_new_fatal_failure_; 170 | TestPartResultReporterInterface* original_reporter_; 171 | 172 | GTEST_DISALLOW_COPY_AND_ASSIGN_(HasNewFatalFailureHelper); 173 | }; 174 | 175 | } // namespace internal 176 | 177 | } // namespace testing 178 | 179 | #endif // GTEST_INCLUDE_GTEST_GTEST_TEST_PART_H_ 180 | -------------------------------------------------------------------------------- /cxx/external/unittest/googlemock/src/gmock-internal-utils.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2007, Google Inc. 2 | // All rights reserved. 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are 6 | // met: 7 | // 8 | // * Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above 11 | // copyright notice, this list of conditions and the following disclaimer 12 | // in the documentation and/or other materials provided with the 13 | // distribution. 14 | // * Neither the name of Google Inc. nor the names of its 15 | // contributors may be used to endorse or promote products derived from 16 | // this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | // 30 | // Author: wan@google.com (Zhanyong Wan) 31 | 32 | // Google Mock - a framework for writing C++ mock classes. 33 | // 34 | // This file defines some utilities useful for implementing Google 35 | // Mock. They are subject to change without notice, so please DO NOT 36 | // USE THEM IN USER CODE. 37 | 38 | #include "gmock/internal/gmock-internal-utils.h" 39 | 40 | #include 41 | #include // NOLINT 42 | #include 43 | #include "gmock/gmock.h" 44 | #include "gmock/internal/gmock-port.h" 45 | #include "gtest/gtest.h" 46 | 47 | namespace testing { 48 | namespace internal { 49 | 50 | // Converts an identifier name to a space-separated list of lower-case 51 | // words. Each maximum substring of the form [A-Za-z][a-z]*|\d+ is 52 | // treated as one word. For example, both "FooBar123" and 53 | // "foo_bar_123" are converted to "foo bar 123". 54 | GTEST_API_ string ConvertIdentifierNameToWords(const char* id_name) { 55 | string result; 56 | char prev_char = '\0'; 57 | for (const char* p = id_name; *p != '\0'; prev_char = *(p++)) { 58 | // We don't care about the current locale as the input is 59 | // guaranteed to be a valid C++ identifier name. 60 | const bool starts_new_word = IsUpper(*p) || 61 | (!IsAlpha(prev_char) && IsLower(*p)) || 62 | (!IsDigit(prev_char) && IsDigit(*p)); 63 | 64 | if (IsAlNum(*p)) { 65 | if (starts_new_word && result != "") 66 | result += ' '; 67 | result += ToLower(*p); 68 | } 69 | } 70 | return result; 71 | } 72 | 73 | // This class reports Google Mock failures as Google Test failures. A 74 | // user can define another class in a similar fashion if he intends to 75 | // use Google Mock with a testing framework other than Google Test. 76 | class GoogleTestFailureReporter : public FailureReporterInterface { 77 | public: 78 | virtual void ReportFailure(FailureType type, const char* file, int line, 79 | const string& message) { 80 | AssertHelper(type == kFatal ? 81 | TestPartResult::kFatalFailure : 82 | TestPartResult::kNonFatalFailure, 83 | file, 84 | line, 85 | message.c_str()) = Message(); 86 | if (type == kFatal) { 87 | posix::Abort(); 88 | } 89 | } 90 | }; 91 | 92 | // Returns the global failure reporter. Will create a 93 | // GoogleTestFailureReporter and return it the first time called. 94 | GTEST_API_ FailureReporterInterface* GetFailureReporter() { 95 | // Points to the global failure reporter used by Google Mock. gcc 96 | // guarantees that the following use of failure_reporter is 97 | // thread-safe. We may need to add additional synchronization to 98 | // protect failure_reporter if we port Google Mock to other 99 | // compilers. 100 | static FailureReporterInterface* const failure_reporter = 101 | new GoogleTestFailureReporter(); 102 | return failure_reporter; 103 | } 104 | 105 | // Protects global resources (stdout in particular) used by Log(). 106 | static GTEST_DEFINE_STATIC_MUTEX_(g_log_mutex); 107 | 108 | // Returns true iff a log with the given severity is visible according 109 | // to the --gmock_verbose flag. 110 | GTEST_API_ bool LogIsVisible(LogSeverity severity) { 111 | if (GMOCK_FLAG(verbose) == kInfoVerbosity) { 112 | // Always show the log if --gmock_verbose=info. 113 | return true; 114 | } else if (GMOCK_FLAG(verbose) == kErrorVerbosity) { 115 | // Always hide it if --gmock_verbose=error. 116 | return false; 117 | } else { 118 | // If --gmock_verbose is neither "info" nor "error", we treat it 119 | // as "warning" (its default value). 120 | return severity == kWarning; 121 | } 122 | } 123 | 124 | // Prints the given message to stdout iff 'severity' >= the level 125 | // specified by the --gmock_verbose flag. If stack_frames_to_skip >= 126 | // 0, also prints the stack trace excluding the top 127 | // stack_frames_to_skip frames. In opt mode, any positive 128 | // stack_frames_to_skip is treated as 0, since we don't know which 129 | // function calls will be inlined by the compiler and need to be 130 | // conservative. 131 | GTEST_API_ void Log(LogSeverity severity, 132 | const string& message, 133 | int stack_frames_to_skip) { 134 | if (!LogIsVisible(severity)) 135 | return; 136 | 137 | // Ensures that logs from different threads don't interleave. 138 | MutexLock l(&g_log_mutex); 139 | 140 | // "using ::std::cout;" doesn't work with Symbian's STLport, where cout is a 141 | // macro. 142 | 143 | if (severity == kWarning) { 144 | // Prints a GMOCK WARNING marker to make the warnings easily searchable. 145 | std::cout << "\nGMOCK WARNING:"; 146 | } 147 | // Pre-pends a new-line to message if it doesn't start with one. 148 | if (message.empty() || message[0] != '\n') { 149 | std::cout << "\n"; 150 | } 151 | std::cout << message; 152 | if (stack_frames_to_skip >= 0) { 153 | #ifdef NDEBUG 154 | // In opt mode, we have to be conservative and skip no stack frame. 155 | const int actual_to_skip = 0; 156 | #else 157 | // In dbg mode, we can do what the caller tell us to do (plus one 158 | // for skipping this function's stack frame). 159 | const int actual_to_skip = stack_frames_to_skip + 1; 160 | #endif // NDEBUG 161 | 162 | // Appends a new-line to message if it doesn't end with one. 163 | if (!message.empty() && *message.rbegin() != '\n') { 164 | std::cout << "\n"; 165 | } 166 | std::cout << "Stack trace:\n" 167 | << ::testing::internal::GetCurrentOsStackTraceExceptTop( 168 | ::testing::UnitTest::GetInstance(), actual_to_skip); 169 | } 170 | std::cout << ::std::flush; 171 | } 172 | 173 | } // namespace internal 174 | } // namespace testing 175 | -------------------------------------------------------------------------------- /cxx/external/unittest/googletest/include/gtest/internal/gtest-string.h: -------------------------------------------------------------------------------- 1 | // Copyright 2005, Google Inc. 2 | // All rights reserved. 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are 6 | // met: 7 | // 8 | // * Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above 11 | // copyright notice, this list of conditions and the following disclaimer 12 | // in the documentation and/or other materials provided with the 13 | // distribution. 14 | // * Neither the name of Google Inc. nor the names of its 15 | // contributors may be used to endorse or promote products derived from 16 | // this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | // 30 | // Authors: wan@google.com (Zhanyong Wan), eefacm@gmail.com (Sean Mcafee) 31 | // 32 | // The Google C++ Testing Framework (Google Test) 33 | // 34 | // This header file declares the String class and functions used internally by 35 | // Google Test. They are subject to change without notice. They should not used 36 | // by code external to Google Test. 37 | // 38 | // This header file is #included by . 39 | // It should not be #included by other files. 40 | 41 | #ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_STRING_H_ 42 | #define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_STRING_H_ 43 | 44 | #ifdef __BORLANDC__ 45 | // string.h is not guaranteed to provide strcpy on C++ Builder. 46 | # include 47 | #endif 48 | 49 | #include 50 | #include 51 | 52 | #include "gtest/internal/gtest-port.h" 53 | 54 | namespace testing { 55 | namespace internal { 56 | 57 | // String - an abstract class holding static string utilities. 58 | class GTEST_API_ String { 59 | public: 60 | // Static utility methods 61 | 62 | // Clones a 0-terminated C string, allocating memory using new. The 63 | // caller is responsible for deleting the return value using 64 | // delete[]. Returns the cloned string, or NULL if the input is 65 | // NULL. 66 | // 67 | // This is different from strdup() in string.h, which allocates 68 | // memory using malloc(). 69 | static const char* CloneCString(const char* c_str); 70 | 71 | #if GTEST_OS_WINDOWS_MOBILE 72 | // Windows CE does not have the 'ANSI' versions of Win32 APIs. To be 73 | // able to pass strings to Win32 APIs on CE we need to convert them 74 | // to 'Unicode', UTF-16. 75 | 76 | // Creates a UTF-16 wide string from the given ANSI string, allocating 77 | // memory using new. The caller is responsible for deleting the return 78 | // value using delete[]. Returns the wide string, or NULL if the 79 | // input is NULL. 80 | // 81 | // The wide string is created using the ANSI codepage (CP_ACP) to 82 | // match the behaviour of the ANSI versions of Win32 calls and the 83 | // C runtime. 84 | static LPCWSTR AnsiToUtf16(const char* c_str); 85 | 86 | // Creates an ANSI string from the given wide string, allocating 87 | // memory using new. The caller is responsible for deleting the return 88 | // value using delete[]. Returns the ANSI string, or NULL if the 89 | // input is NULL. 90 | // 91 | // The returned string is created using the ANSI codepage (CP_ACP) to 92 | // match the behaviour of the ANSI versions of Win32 calls and the 93 | // C runtime. 94 | static const char* Utf16ToAnsi(LPCWSTR utf16_str); 95 | #endif 96 | 97 | // Compares two C strings. Returns true iff they have the same content. 98 | // 99 | // Unlike strcmp(), this function can handle NULL argument(s). A 100 | // NULL C string is considered different to any non-NULL C string, 101 | // including the empty string. 102 | static bool CStringEquals(const char* lhs, const char* rhs); 103 | 104 | // Converts a wide C string to a String using the UTF-8 encoding. 105 | // NULL will be converted to "(null)". If an error occurred during 106 | // the conversion, "(failed to convert from wide string)" is 107 | // returned. 108 | static std::string ShowWideCString(const wchar_t* wide_c_str); 109 | 110 | // Compares two wide C strings. Returns true iff they have the same 111 | // content. 112 | // 113 | // Unlike wcscmp(), this function can handle NULL argument(s). A 114 | // NULL C string is considered different to any non-NULL C string, 115 | // including the empty string. 116 | static bool WideCStringEquals(const wchar_t* lhs, const wchar_t* rhs); 117 | 118 | // Compares two C strings, ignoring case. Returns true iff they 119 | // have the same content. 120 | // 121 | // Unlike strcasecmp(), this function can handle NULL argument(s). 122 | // A NULL C string is considered different to any non-NULL C string, 123 | // including the empty string. 124 | static bool CaseInsensitiveCStringEquals(const char* lhs, 125 | const char* rhs); 126 | 127 | // Compares two wide C strings, ignoring case. Returns true iff they 128 | // have the same content. 129 | // 130 | // Unlike wcscasecmp(), this function can handle NULL argument(s). 131 | // A NULL C string is considered different to any non-NULL wide C string, 132 | // including the empty string. 133 | // NB: The implementations on different platforms slightly differ. 134 | // On windows, this method uses _wcsicmp which compares according to LC_CTYPE 135 | // environment variable. On GNU platform this method uses wcscasecmp 136 | // which compares according to LC_CTYPE category of the current locale. 137 | // On MacOS X, it uses towlower, which also uses LC_CTYPE category of the 138 | // current locale. 139 | static bool CaseInsensitiveWideCStringEquals(const wchar_t* lhs, 140 | const wchar_t* rhs); 141 | 142 | // Returns true iff the given string ends with the given suffix, ignoring 143 | // case. Any string is considered to end with an empty suffix. 144 | static bool EndsWithCaseInsensitive( 145 | const std::string& str, const std::string& suffix); 146 | 147 | // Formats an int value as "%02d". 148 | static std::string FormatIntWidth2(int value); // "%02d" for width == 2 149 | 150 | // Formats an int value as "%X". 151 | static std::string FormatHexInt(int value); 152 | 153 | // Formats a byte as "%02X". 154 | static std::string FormatByte(unsigned char value); 155 | 156 | private: 157 | String(); // Not meant to be instantiated. 158 | }; // class String 159 | 160 | // Gets the content of the stringstream's buffer as an std::string. Each '\0' 161 | // character in the buffer is replaced with "\\0". 162 | GTEST_API_ std::string StringStreamToString(::std::stringstream* stream); 163 | 164 | } // namespace internal 165 | } // namespace testing 166 | 167 | #endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_STRING_H_ 168 | -------------------------------------------------------------------------------- /cxx/external/unittest/googlemock/src/gmock.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2008, Google Inc. 2 | // All rights reserved. 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are 6 | // met: 7 | // 8 | // * Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above 11 | // copyright notice, this list of conditions and the following disclaimer 12 | // in the documentation and/or other materials provided with the 13 | // distribution. 14 | // * Neither the name of Google Inc. nor the names of its 15 | // contributors may be used to endorse or promote products derived from 16 | // this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | // 30 | // Author: wan@google.com (Zhanyong Wan) 31 | 32 | #include "gmock/gmock.h" 33 | #include "gmock/internal/gmock-port.h" 34 | 35 | namespace testing { 36 | 37 | // TODO(wan@google.com): support using environment variables to 38 | // control the flag values, like what Google Test does. 39 | 40 | GMOCK_DEFINE_bool_(catch_leaked_mocks, true, 41 | "true iff Google Mock should report leaked mock objects " 42 | "as failures."); 43 | 44 | GMOCK_DEFINE_string_(verbose, internal::kWarningVerbosity, 45 | "Controls how verbose Google Mock's output is." 46 | " Valid values:\n" 47 | " info - prints all messages.\n" 48 | " warning - prints warnings and errors.\n" 49 | " error - prints errors only."); 50 | 51 | namespace internal { 52 | 53 | // Parses a string as a command line flag. The string should have the 54 | // format "--gmock_flag=value". When def_optional is true, the 55 | // "=value" part can be omitted. 56 | // 57 | // Returns the value of the flag, or NULL if the parsing failed. 58 | static const char* ParseGoogleMockFlagValue(const char* str, 59 | const char* flag, 60 | bool def_optional) { 61 | // str and flag must not be NULL. 62 | if (str == NULL || flag == NULL) return NULL; 63 | 64 | // The flag must start with "--gmock_". 65 | const std::string flag_str = std::string("--gmock_") + flag; 66 | const size_t flag_len = flag_str.length(); 67 | if (strncmp(str, flag_str.c_str(), flag_len) != 0) return NULL; 68 | 69 | // Skips the flag name. 70 | const char* flag_end = str + flag_len; 71 | 72 | // When def_optional is true, it's OK to not have a "=value" part. 73 | if (def_optional && (flag_end[0] == '\0')) { 74 | return flag_end; 75 | } 76 | 77 | // If def_optional is true and there are more characters after the 78 | // flag name, or if def_optional is false, there must be a '=' after 79 | // the flag name. 80 | if (flag_end[0] != '=') return NULL; 81 | 82 | // Returns the string after "=". 83 | return flag_end + 1; 84 | } 85 | 86 | // Parses a string for a Google Mock bool flag, in the form of 87 | // "--gmock_flag=value". 88 | // 89 | // On success, stores the value of the flag in *value, and returns 90 | // true. On failure, returns false without changing *value. 91 | static bool ParseGoogleMockBoolFlag(const char* str, const char* flag, 92 | bool* value) { 93 | // Gets the value of the flag as a string. 94 | const char* const value_str = ParseGoogleMockFlagValue(str, flag, true); 95 | 96 | // Aborts if the parsing failed. 97 | if (value_str == NULL) return false; 98 | 99 | // Converts the string value to a bool. 100 | *value = !(*value_str == '0' || *value_str == 'f' || *value_str == 'F'); 101 | return true; 102 | } 103 | 104 | // Parses a string for a Google Mock string flag, in the form of 105 | // "--gmock_flag=value". 106 | // 107 | // On success, stores the value of the flag in *value, and returns 108 | // true. On failure, returns false without changing *value. 109 | template 110 | static bool ParseGoogleMockStringFlag(const char* str, const char* flag, 111 | String* value) { 112 | // Gets the value of the flag as a string. 113 | const char* const value_str = ParseGoogleMockFlagValue(str, flag, false); 114 | 115 | // Aborts if the parsing failed. 116 | if (value_str == NULL) return false; 117 | 118 | // Sets *value to the value of the flag. 119 | *value = value_str; 120 | return true; 121 | } 122 | 123 | // The internal implementation of InitGoogleMock(). 124 | // 125 | // The type parameter CharType can be instantiated to either char or 126 | // wchar_t. 127 | template 128 | void InitGoogleMockImpl(int* argc, CharType** argv) { 129 | // Makes sure Google Test is initialized. InitGoogleTest() is 130 | // idempotent, so it's fine if the user has already called it. 131 | InitGoogleTest(argc, argv); 132 | if (*argc <= 0) return; 133 | 134 | for (int i = 1; i != *argc; i++) { 135 | const std::string arg_string = StreamableToString(argv[i]); 136 | const char* const arg = arg_string.c_str(); 137 | 138 | // Do we see a Google Mock flag? 139 | if (ParseGoogleMockBoolFlag(arg, "catch_leaked_mocks", 140 | &GMOCK_FLAG(catch_leaked_mocks)) || 141 | ParseGoogleMockStringFlag(arg, "verbose", &GMOCK_FLAG(verbose))) { 142 | // Yes. Shift the remainder of the argv list left by one. Note 143 | // that argv has (*argc + 1) elements, the last one always being 144 | // NULL. The following loop moves the trailing NULL element as 145 | // well. 146 | for (int j = i; j != *argc; j++) { 147 | argv[j] = argv[j + 1]; 148 | } 149 | 150 | // Decrements the argument count. 151 | (*argc)--; 152 | 153 | // We also need to decrement the iterator as we just removed 154 | // an element. 155 | i--; 156 | } 157 | } 158 | } 159 | 160 | } // namespace internal 161 | 162 | // Initializes Google Mock. This must be called before running the 163 | // tests. In particular, it parses a command line for the flags that 164 | // Google Mock recognizes. Whenever a Google Mock flag is seen, it is 165 | // removed from argv, and *argc is decremented. 166 | // 167 | // No value is returned. Instead, the Google Mock flag variables are 168 | // updated. 169 | // 170 | // Since Google Test is needed for Google Mock to work, this function 171 | // also initializes Google Test and parses its flags, if that hasn't 172 | // been done. 173 | GTEST_API_ void InitGoogleMock(int* argc, char** argv) { 174 | internal::InitGoogleMockImpl(argc, argv); 175 | } 176 | 177 | // This overloaded version can be used in Windows programs compiled in 178 | // UNICODE mode. 179 | GTEST_API_ void InitGoogleMock(int* argc, wchar_t** argv) { 180 | internal::InitGoogleMockImpl(argc, argv); 181 | } 182 | 183 | } // namespace testing 184 | -------------------------------------------------------------------------------- /cxx/lib/Support/CharacterProperties.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Facebook, Inc. and its affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #include "s2020/Support/CharacterProperties.h" 9 | #include "s2020/Support/CodePointSet.h" 10 | 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | namespace s2020 { 17 | 18 | #include "UnicodeData.inc" 19 | 20 | namespace { 21 | struct UnicodeRangeComp { 22 | bool operator()(UnicodeRange p, uint32_t s) const { 23 | return p.second < s; 24 | } 25 | bool operator()(uint32_t s, UnicodeRange p) const { 26 | return s < p.first; 27 | } 28 | }; 29 | } // namespace 30 | 31 | template 32 | inline bool lookup(const UnicodeRangeTable &table, const uint32_t cp) { 33 | return std::binary_search( 34 | std::begin(table), std::end(table), cp, UnicodeRangeComp()); 35 | } 36 | 37 | bool isUnicodeOnlyLetter(uint32_t cp) { 38 | // "any character in the Unicode categories “Uppercase letter (Lu)”, 39 | // “Lowercase letter (Ll)”, “Titlecase letter (Lt)”, “Modifier letter (Lm)”, 40 | // “Other letter (Lo)”, or “Letter number (Nl)”". 41 | // ASCII characters are not "UnicodeOnly" and so we return false. 42 | if (cp <= 0x7F) 43 | return false; 44 | 45 | return lookup(UNICODE_LETTERS, cp); 46 | } 47 | 48 | // Special cased due to small number of separate values. 49 | bool isUnicodeOnlySpace(uint32_t cp) { 50 | // "Other category “Zs”: Any other Unicode “space separator”" 51 | // Exclude ASCII. 52 | if (cp <= 0x7F) 53 | return false; 54 | 55 | switch (cp) { 56 | case 0xa0: 57 | case 0x1680: 58 | case 0x2000: 59 | case 0x2001: 60 | case 0x2002: 61 | case 0x2003: 62 | case 0x2004: 63 | case 0x2005: 64 | case 0x2006: 65 | case 0x2007: 66 | case 0x2008: 67 | case 0x2009: 68 | case 0x200a: 69 | case 0x202f: 70 | case 0x205f: 71 | case 0x3000: 72 | return true; 73 | default: 74 | return false; 75 | } 76 | } 77 | 78 | bool isUnicodeCombiningMark(uint32_t cp) { 79 | // "any character in the Unicode categories “Non-spacing mark (Mn)” or 80 | // “Combining spacing mark (Mc)”" 81 | return lookup(UNICODE_COMBINING_MARK, cp); 82 | } 83 | 84 | bool isUnicodeDigit(uint32_t cp) { 85 | // "any character in the Unicode category “Decimal number (Nd)”" 86 | // 0-9 is the common case. 87 | return (cp >= '0' && cp <= '9') || lookup(UNICODE_DIGIT, cp); 88 | }; 89 | 90 | bool isUnicodeConnectorPunctuation(uint32_t cp) { 91 | // "any character in the Unicode category “Connector punctuation (Pc)" 92 | // _ is the common case. 93 | return cp == '_' || lookup(UNICODE_CONNECTOR_PUNCTUATION, cp); 94 | } 95 | 96 | static uint32_t applyTransform(const UnicodeTransformRange &r, uint32_t cp) { 97 | assert( 98 | r.start <= cp && cp < r.start + r.count && 99 | "range does not contain this cp"); 100 | assert(cp <= INT32_MAX && "cp is too big"); 101 | // Check if our code point has a mod of 0. 102 | if ((cp - r.start) % r.modulo == 0) { 103 | int32_t cps = static_cast(cp) + r.delta; 104 | assert(cps >= 0 && "delta underflowed"); 105 | return static_cast(cps); 106 | } 107 | return cp; 108 | } 109 | 110 | // Predicate used to enable binary search on UnicodeTransformRange. 111 | // Here we return true if the last element of the range is < cp, so <= is 112 | // correct. 113 | static bool operator<(const UnicodeTransformRange &m, uint32_t cp) { 114 | return m.start + m.count <= cp; 115 | } 116 | 117 | /// Find all code points which canonicalize to a value in \p range, and add them 118 | /// to \p receiver. This is a slow linear search across all ranges. 119 | static void addPrecanonicalCharacters( 120 | CodePointRange range, 121 | CodePointSet *receiver, 122 | bool unicode) { 123 | if (range.length == 0) 124 | return; 125 | // TODO: if range is ASCII and unicode is not set, we can stop the search 126 | // after the ASCII part as nothing outside ASCII can canonicalize to an ASCII 127 | // character. 128 | const auto start = 129 | unicode ? std::begin(UNICODE_FOLDS) : std::begin(LEGACY_CANONS); 130 | const auto end = unicode ? std::end(UNICODE_FOLDS) : std::end(LEGACY_CANONS); 131 | for (auto iter = start; iter != end; ++iter) { 132 | const UnicodeTransformRange &transform = *iter; 133 | // Get the range of transformed-from and transformed-to characters. 134 | CodePointRange fromRange{transform.start, transform.count}; 135 | CodePointRange toRange = fromRange; 136 | toRange.first += transform.delta; 137 | 138 | // See if some character in our range will be transformed-to. 139 | if (!range.overlaps(toRange)) 140 | continue; 141 | 142 | // Looks like it. Add everything. 143 | for (uint32_t cp = fromRange.first; cp < fromRange.end(); cp++) { 144 | uint32_t tcp = applyTransform(transform, cp); 145 | if (tcp != cp && range.first <= tcp && tcp < range.end()) { 146 | receiver->add(cp); 147 | } 148 | } 149 | } 150 | } 151 | 152 | /// For each code point in \p range, canonicalize it and add the canonicalized 153 | /// values to \p receiver. 154 | static void 155 | canonicalizeRange(CodePointRange range, CodePointSet *receiver, bool unicode) { 156 | assert(range.length > 0 && "Range should never be empty"); 157 | 158 | /// Find the first transform that contains or starts after our range. 159 | const auto start = 160 | unicode ? std::begin(UNICODE_FOLDS) : std::begin(LEGACY_CANONS); 161 | const auto end = unicode ? std::end(UNICODE_FOLDS) : std::end(LEGACY_CANONS); 162 | auto transform = std::lower_bound(start, end, range.first); 163 | 164 | uint32_t curcp = range.first; 165 | uint32_t endcp = range.end(); 166 | while (curcp < endcp && transform != end) { 167 | uint32_t transformEnd = transform->start + transform->count; 168 | assert(transformEnd > curcp && "transform should end after our current cp"); 169 | if (transform->start > curcp) { 170 | // Our transform started after the current value, so skip to the 171 | // transform. 172 | curcp = transform->start; 173 | } else { 174 | // Apply this transform for the code points that are in the transform and 175 | // also in our range. 176 | for (; curcp < transformEnd && curcp < endcp; curcp++) { 177 | receiver->add(applyTransform(*transform, curcp)); 178 | } 179 | // We have now exhausted this transform; go to the next one. 180 | ++transform; 181 | } 182 | } 183 | } 184 | 185 | CodePointSet makeCanonicallyEquivalent(const CodePointSet &set, bool unicode) { 186 | // Canonicalize all characters in the set, and then find all characters which 187 | // canonicalize to some element in the set. 188 | CodePointSet canonicalized = set; 189 | for (const auto &range : set.ranges()) { 190 | canonicalizeRange(range, &canonicalized, unicode); 191 | } 192 | 193 | CodePointSet result = canonicalized; 194 | for (const auto &range : canonicalized.ranges()) { 195 | addPrecanonicalCharacters(range, &result, unicode); 196 | } 197 | return result; 198 | } 199 | 200 | uint32_t canonicalize(uint32_t cp, bool unicode) { 201 | const auto start = 202 | unicode ? std::begin(UNICODE_FOLDS) : std::begin(LEGACY_CANONS); 203 | const auto end = unicode ? std::end(UNICODE_FOLDS) : std::end(LEGACY_CANONS); 204 | auto where = std::lower_bound(start, end, cp); 205 | if (where != end && where->start <= cp && cp < where->start + where->count) { 206 | return applyTransform(*where, cp); 207 | } else { 208 | // No transform for this character, so it canonicalizes to itself. 209 | return cp; 210 | } 211 | } 212 | 213 | } // namespace s2020 214 | -------------------------------------------------------------------------------- /cxx/include/s2020/Support/UTF8.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Facebook, Inc. and its affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #ifndef S2020_SUPPORT_UTF8_H 9 | #define S2020_SUPPORT_UTF8_H 10 | 11 | #include "s2020/Support/CharacterProperties.h" 12 | 13 | #include "llvm/ADT/ArrayRef.h" 14 | #include "llvm/ADT/Twine.h" 15 | #include "llvm/Support/Compiler.h" 16 | 17 | #include 18 | 19 | namespace s2020 { 20 | 21 | /// Maximum number of bytes in a valid UTF-8 codepoint 22 | constexpr size_t UTF8CodepointMaxBytes = 6; 23 | 24 | /// Encode a unicode code point as a UTF-8 sequence of bytes. 25 | void encodeUTF8(char *&dst, uint32_t cp); 26 | 27 | /// Check whether a byte is a regular ASCII or a UTF8 starting byte. 28 | /// \return true if it is UTF8 starting byte. 29 | inline bool isUTF8Start(char ch) { 30 | return (ch & 0x80) != 0; 31 | } 32 | 33 | /// \return true if this is a UTF-8 leading byte. 34 | inline bool isUTF8LeadingByte(char ch) { 35 | return (ch & 0xC0) == 0xC0; 36 | } 37 | 38 | /// \return true if this is a UTF-8 continuation byte, or in other words, this 39 | /// is a byte in the "middle" of a UTF-8 codepoint. 40 | inline static bool isUTF8ContinuationByte(char ch) { 41 | return (ch & 0xC0) == 0x80; 42 | } 43 | 44 | /// \return true if this is a pure ASCII char sequence. 45 | template 46 | inline bool isAllASCII(Iter begin, Iter end) { 47 | while (begin < end) { 48 | if (*begin < 0 || *begin > 127) 49 | return false; 50 | ++begin; 51 | } 52 | return true; 53 | } 54 | 55 | /// Overload for char* and uint8_t*. 56 | bool isAllASCII(const uint8_t *start, const uint8_t *end); 57 | 58 | inline bool isAllASCII(const char *start, const char *end) { 59 | return isAllASCII((const uint8_t *)start, (const uint8_t *)end); 60 | } 61 | 62 | /// Decode a sequence of UTF8 encoded bytes when it is known that the first byte 63 | /// is a start of an UTF8 sequence. 64 | /// \tparam allowSurrogates when false, values in the surrogate range are 65 | /// reported as errors 66 | template 67 | uint32_t _decodeUTF8SlowPath(const char *&from, F error) { 68 | uint32_t ch = (uint32_t)from[0]; 69 | uint32_t result; 70 | 71 | assert(isUTF8Start(ch)); 72 | 73 | if (LLVM_LIKELY((ch & 0xE0) == 0xC0)) { 74 | uint32_t ch1 = (uint32_t)from[1]; 75 | if (LLVM_UNLIKELY((ch1 & 0xC0) != 0x80)) { 76 | from += 1; 77 | error("Invalid UTF-8 continuation byte"); 78 | return UNICODE_REPLACEMENT_CHARACTER; 79 | } 80 | 81 | from += 2; 82 | result = ((ch & 0x1F) << 6) | (ch1 & 0x3F); 83 | if (LLVM_UNLIKELY(result <= 0x7F)) { 84 | error("Non-canonical UTF-8 encoding"); 85 | return UNICODE_REPLACEMENT_CHARACTER; 86 | } 87 | 88 | } else if (LLVM_LIKELY((ch & 0xF0) == 0xE0)) { 89 | uint32_t ch1 = (uint32_t)from[1]; 90 | if (LLVM_UNLIKELY((ch1 & 0x40) != 0 || (ch1 & 0x80) == 0)) { 91 | from += 1; 92 | error("Invalid UTF-8 continuation byte"); 93 | return UNICODE_REPLACEMENT_CHARACTER; 94 | } 95 | uint32_t ch2 = (uint32_t)from[2]; 96 | if (LLVM_UNLIKELY((ch2 & 0x40) != 0 || (ch2 & 0x80) == 0)) { 97 | from += 2; 98 | error("Invalid UTF-8 continuation byte"); 99 | return UNICODE_REPLACEMENT_CHARACTER; 100 | } 101 | from += 3; 102 | result = ((ch & 0x0F) << 12) | ((ch1 & 0x3F) << 6) | (ch2 & 0x3F); 103 | if (LLVM_UNLIKELY(result <= 0x7FF)) { 104 | error("Non-canonical UTF-8 encoding"); 105 | return UNICODE_REPLACEMENT_CHARACTER; 106 | } 107 | if (LLVM_UNLIKELY( 108 | result >= UNICODE_SURROGATE_FIRST && 109 | result <= UNICODE_SURROGATE_LAST && !allowSurrogates)) { 110 | error("Invalid UTF-8 code point 0x" + llvm::Twine::utohexstr(result)); 111 | return UNICODE_REPLACEMENT_CHARACTER; 112 | } 113 | 114 | } else if ((ch & 0xF8) == 0xF0) { 115 | uint32_t ch1 = (uint32_t)from[1]; 116 | if (LLVM_UNLIKELY((ch1 & 0x40) != 0 || (ch1 & 0x80) == 0)) { 117 | from += 1; 118 | error("Invalid UTF-8 continuation byte"); 119 | return UNICODE_REPLACEMENT_CHARACTER; 120 | } 121 | uint32_t ch2 = (uint32_t)from[2]; 122 | if (LLVM_UNLIKELY((ch2 & 0x40) != 0 || (ch2 & 0x80) == 0)) { 123 | from += 2; 124 | error("Invalid UTF-8 continuation byte"); 125 | return UNICODE_REPLACEMENT_CHARACTER; 126 | } 127 | uint32_t ch3 = (uint32_t)from[3]; 128 | if (LLVM_UNLIKELY((ch3 & 0x40) != 0 || (ch3 & 0x80) == 0)) { 129 | from += 3; 130 | error("Invalid UTF-8 continuation byte"); 131 | return UNICODE_REPLACEMENT_CHARACTER; 132 | } 133 | from += 4; 134 | result = ((ch & 0x07) << 18) | ((ch1 & 0x3F) << 12) | ((ch2 & 0x3F) << 6) | 135 | (ch3 & 0x3F); 136 | if (LLVM_UNLIKELY(result <= 0xFFFF)) { 137 | error("Non-canonical UTF-8 encoding"); 138 | return UNICODE_REPLACEMENT_CHARACTER; 139 | } 140 | if (LLVM_UNLIKELY(result > UNICODE_MAX_VALUE)) { 141 | error("Invalid UTF-8 code point 0x" + llvm::Twine::utohexstr(result)); 142 | return UNICODE_REPLACEMENT_CHARACTER; 143 | } 144 | 145 | } else { 146 | from += 1; 147 | error("Invalid UTF-8 lead byte 0x" + llvm::Twine::utohexstr(ch)); 148 | return UNICODE_REPLACEMENT_CHARACTER; 149 | } 150 | 151 | return result; 152 | } 153 | 154 | /// Scans back from \p ptr until the start of the previous UTF-8 codepoint. 155 | /// Logically, this is equivalent to `--ptr` in the codepoint space. 156 | /// It could be a regular ASCII character, or a multi-byte encoded character. 157 | /// This function assumes that the input is valid! 158 | inline const char *previousUTF8Start(const char *ptr) { 159 | --ptr; 160 | // If the previous codepoint is ASCII, we are done. 161 | if (!(*ptr & 0x80)) 162 | return ptr; 163 | // Scan backwards until we find a leading byte (11xxxxxx) 164 | while ((*ptr & 0xC0) != 0xC0) 165 | --ptr; 166 | return ptr; 167 | } 168 | 169 | /// Decode a sequence of UTF8 encoded bytes into a Unicode codepoint. 170 | /// In case of decoding errors, the provided callback is invoked with an 171 | /// apropriate messsage and UNICODE_REPLACEMENT_CHARACTER is returned. 172 | /// 173 | /// \tparam allowSurrogates when false, values in the surrogate range are 174 | /// reported as errors 175 | /// \param error callback invoked with an error message 176 | /// \return the codepoint 177 | template 178 | inline uint32_t decodeUTF8(const char *&from, F error) { 179 | if (LLVM_LIKELY((*from & 0x80) == 0)) // Ordinary ASCII? 180 | return *from++; 181 | 182 | return _decodeUTF8SlowPath(from, error); 183 | } 184 | 185 | /// Encode a 32-bit value, into UTF16. If the value is a part of a surrogate 186 | /// pair, it is encoded without any conversion. 187 | template 188 | inline void encodeUTF16(OutIt &dest, uint32_t cp) { 189 | if (LLVM_LIKELY(cp < 0x10000)) { 190 | *dest = (uint16_t)cp; 191 | ++dest; // Use pre-increment in case this is an iterator. 192 | } else { 193 | assert(cp <= UNICODE_MAX_VALUE && "invalid Unicode value"); 194 | cp -= 0x10000; 195 | *dest = UTF16_HIGH_SURROGATE + ((cp >> 10) & 0x3FF); 196 | ++dest; 197 | *dest = UTF16_LOW_SURROGATE + (cp & 0x3FF); 198 | ++dest; 199 | } 200 | } 201 | 202 | /// Decode a UTF-8 sequence, which is assumed to be valid, but may possibly 203 | /// contain explicitly encoded surrogate pairs, into a UTF-16 sequence. 204 | /// \return the updated destination iterator 205 | template 206 | inline OutIt convertUTF8WithSurrogatesToUTF16( 207 | OutIt dest, 208 | const char *begin8, 209 | const char *end8) { 210 | while (begin8 < end8) 211 | encodeUTF16(dest, decodeUTF8(begin8, [](const llvm::Twine &) { 212 | llvm_unreachable("invalid UTF-8"); 213 | })); 214 | return dest; 215 | } 216 | 217 | /// Convert a UTF-16 encoded string \p input to UTF-8 stored in \p dest, 218 | /// encoding each surrogate halves individully into UTF-8. 219 | /// This is the inverse function of convertUTF8WithSurrogatesToUTF16. 220 | /// Note the result is not valid utf-8 if it contains surrogate values. 221 | /// Only use it to get the internal representation of utf-8 strings in s2020 222 | /// compiler. 223 | void convertUTF16ToUTF8WithSingleSurrogates( 224 | std::string &dest, 225 | llvm::ArrayRef input); 226 | 227 | /// Convert a UTF-16 encoded string \p input to UTF-8 stored in \p dest, 228 | /// replacing unpaired surrogates halves with the Unicode replacement character. 229 | /// \param maxCharacters If non-zero, the maximum number of characters to 230 | /// convert. 231 | /// \return false if the string was truncated, true if the whole string was 232 | /// written out successfully. 233 | bool convertUTF16ToUTF8WithReplacements( 234 | std::string &dest, 235 | llvm::ArrayRef input, 236 | size_t maxCharacters = 0); 237 | 238 | } // namespace s2020 239 | 240 | #endif // S2020_SUPPORT_UTF8_H 241 | -------------------------------------------------------------------------------- /cxx/external/unittest/googletest/include/gtest/internal/gtest-linked_ptr.h: -------------------------------------------------------------------------------- 1 | // Copyright 2003 Google Inc. 2 | // All rights reserved. 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are 6 | // met: 7 | // 8 | // * Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above 11 | // copyright notice, this list of conditions and the following disclaimer 12 | // in the documentation and/or other materials provided with the 13 | // distribution. 14 | // * Neither the name of Google Inc. nor the names of its 15 | // contributors may be used to endorse or promote products derived from 16 | // this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | // 30 | // Authors: Dan Egnor (egnor@google.com) 31 | // 32 | // A "smart" pointer type with reference tracking. Every pointer to a 33 | // particular object is kept on a circular linked list. When the last pointer 34 | // to an object is destroyed or reassigned, the object is deleted. 35 | // 36 | // Used properly, this deletes the object when the last reference goes away. 37 | // There are several caveats: 38 | // - Like all reference counting schemes, cycles lead to leaks. 39 | // - Each smart pointer is actually two pointers (8 bytes instead of 4). 40 | // - Every time a pointer is assigned, the entire list of pointers to that 41 | // object is traversed. This class is therefore NOT SUITABLE when there 42 | // will often be more than two or three pointers to a particular object. 43 | // - References are only tracked as long as linked_ptr<> objects are copied. 44 | // If a linked_ptr<> is converted to a raw pointer and back, BAD THINGS 45 | // will happen (double deletion). 46 | // 47 | // A good use of this class is storing object references in STL containers. 48 | // You can safely put linked_ptr<> in a vector<>. 49 | // Other uses may not be as good. 50 | // 51 | // Note: If you use an incomplete type with linked_ptr<>, the class 52 | // *containing* linked_ptr<> must have a constructor and destructor (even 53 | // if they do nothing!). 54 | // 55 | // Bill Gibbons suggested we use something like this. 56 | // 57 | // Thread Safety: 58 | // Unlike other linked_ptr implementations, in this implementation 59 | // a linked_ptr object is thread-safe in the sense that: 60 | // - it's safe to copy linked_ptr objects concurrently, 61 | // - it's safe to copy *from* a linked_ptr and read its underlying 62 | // raw pointer (e.g. via get()) concurrently, and 63 | // - it's safe to write to two linked_ptrs that point to the same 64 | // shared object concurrently. 65 | // TODO(wan@google.com): rename this to safe_linked_ptr to avoid 66 | // confusion with normal linked_ptr. 67 | 68 | #ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_LINKED_PTR_H_ 69 | #define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_LINKED_PTR_H_ 70 | 71 | #include 72 | #include 73 | 74 | #include "gtest/internal/gtest-port.h" 75 | 76 | namespace testing { 77 | namespace internal { 78 | 79 | // Protects copying of all linked_ptr objects. 80 | GTEST_API_ GTEST_DECLARE_STATIC_MUTEX_(g_linked_ptr_mutex); 81 | 82 | // This is used internally by all instances of linked_ptr<>. It needs to be 83 | // a non-template class because different types of linked_ptr<> can refer to 84 | // the same object (linked_ptr(obj) vs linked_ptr(obj)). 85 | // So, it needs to be possible for different types of linked_ptr to participate 86 | // in the same circular linked list, so we need a single class type here. 87 | // 88 | // DO NOT USE THIS CLASS DIRECTLY YOURSELF. Use linked_ptr. 89 | class linked_ptr_internal { 90 | public: 91 | // Create a new circle that includes only this instance. 92 | void join_new() { 93 | next_ = this; 94 | } 95 | 96 | // Many linked_ptr operations may change p.link_ for some linked_ptr 97 | // variable p in the same circle as this object. Therefore we need 98 | // to prevent two such operations from occurring concurrently. 99 | // 100 | // Note that different types of linked_ptr objects can coexist in a 101 | // circle (e.g. linked_ptr, linked_ptr, and 102 | // linked_ptr). Therefore we must use a single mutex to 103 | // protect all linked_ptr objects. This can create serious 104 | // contention in production code, but is acceptable in a testing 105 | // framework. 106 | 107 | // Join an existing circle. 108 | void join(linked_ptr_internal const* ptr) 109 | GTEST_LOCK_EXCLUDED_(g_linked_ptr_mutex) { 110 | MutexLock lock(&g_linked_ptr_mutex); 111 | 112 | linked_ptr_internal const* p = ptr; 113 | while (p->next_ != ptr) { 114 | assert(p->next_ != this && 115 | "Trying to join() a linked ring we are already in. " 116 | "Is GMock thread safety enabled?"); 117 | p = p->next_; 118 | } 119 | p->next_ = this; 120 | next_ = ptr; 121 | } 122 | 123 | // Leave whatever circle we're part of. Returns true if we were the 124 | // last member of the circle. Once this is done, you can join() another. 125 | bool depart() 126 | GTEST_LOCK_EXCLUDED_(g_linked_ptr_mutex) { 127 | MutexLock lock(&g_linked_ptr_mutex); 128 | 129 | if (next_ == this) return true; 130 | linked_ptr_internal const* p = next_; 131 | while (p->next_ != this) { 132 | assert(p->next_ != next_ && 133 | "Trying to depart() a linked ring we are not in. " 134 | "Is GMock thread safety enabled?"); 135 | p = p->next_; 136 | } 137 | p->next_ = next_; 138 | return false; 139 | } 140 | 141 | private: 142 | mutable linked_ptr_internal const* next_; 143 | }; 144 | 145 | template 146 | class linked_ptr { 147 | public: 148 | typedef T element_type; 149 | 150 | // Take over ownership of a raw pointer. This should happen as soon as 151 | // possible after the object is created. 152 | explicit linked_ptr(T* ptr = NULL) { capture(ptr); } 153 | ~linked_ptr() { depart(); } 154 | 155 | // Copy an existing linked_ptr<>, adding ourselves to the list of references. 156 | template linked_ptr(linked_ptr const& ptr) { copy(&ptr); } 157 | linked_ptr(linked_ptr const& ptr) { // NOLINT 158 | assert(&ptr != this); 159 | copy(&ptr); 160 | } 161 | 162 | // Assignment releases the old value and acquires the new. 163 | template linked_ptr& operator=(linked_ptr const& ptr) { 164 | depart(); 165 | copy(&ptr); 166 | return *this; 167 | } 168 | 169 | linked_ptr& operator=(linked_ptr const& ptr) { 170 | if (&ptr != this) { 171 | depart(); 172 | copy(&ptr); 173 | } 174 | return *this; 175 | } 176 | 177 | // Smart pointer members. 178 | void reset(T* ptr = NULL) { 179 | depart(); 180 | capture(ptr); 181 | } 182 | T* get() const { return value_; } 183 | T* operator->() const { return value_; } 184 | T& operator*() const { return *value_; } 185 | 186 | bool operator==(T* p) const { return value_ == p; } 187 | bool operator!=(T* p) const { return value_ != p; } 188 | template 189 | bool operator==(linked_ptr const& ptr) const { 190 | return value_ == ptr.get(); 191 | } 192 | template 193 | bool operator!=(linked_ptr const& ptr) const { 194 | return value_ != ptr.get(); 195 | } 196 | 197 | private: 198 | template 199 | friend class linked_ptr; 200 | 201 | T* value_; 202 | linked_ptr_internal link_; 203 | 204 | void depart() { 205 | if (link_.depart()) delete value_; 206 | } 207 | 208 | void capture(T* ptr) { 209 | value_ = ptr; 210 | link_.join_new(); 211 | } 212 | 213 | template void copy(linked_ptr const* ptr) { 214 | value_ = ptr->get(); 215 | if (value_) 216 | link_.join(&ptr->link_); 217 | else 218 | link_.join_new(); 219 | } 220 | }; 221 | 222 | template inline 223 | bool operator==(T* ptr, const linked_ptr& x) { 224 | return ptr == x.get(); 225 | } 226 | 227 | template inline 228 | bool operator!=(T* ptr, const linked_ptr& x) { 229 | return ptr != x.get(); 230 | } 231 | 232 | // A function to convert T* into linked_ptr 233 | // Doing e.g. make_linked_ptr(new FooBarBaz(arg)) is a shorter notation 234 | // for linked_ptr >(new FooBarBaz(arg)) 235 | template 236 | linked_ptr make_linked_ptr(T* ptr) { 237 | return linked_ptr(ptr); 238 | } 239 | 240 | } // namespace internal 241 | } // namespace testing 242 | 243 | #endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_LINKED_PTR_H_ 244 | -------------------------------------------------------------------------------- /cxx/external/unittest/googletest/include/gtest/gtest-message.h: -------------------------------------------------------------------------------- 1 | // Copyright 2005, Google Inc. 2 | // All rights reserved. 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are 6 | // met: 7 | // 8 | // * Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above 11 | // copyright notice, this list of conditions and the following disclaimer 12 | // in the documentation and/or other materials provided with the 13 | // distribution. 14 | // * Neither the name of Google Inc. nor the names of its 15 | // contributors may be used to endorse or promote products derived from 16 | // this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | // 30 | // Author: wan@google.com (Zhanyong Wan) 31 | // 32 | // The Google C++ Testing Framework (Google Test) 33 | // 34 | // This header file defines the Message class. 35 | // 36 | // IMPORTANT NOTE: Due to limitation of the C++ language, we have to 37 | // leave some internal implementation details in this header file. 38 | // They are clearly marked by comments like this: 39 | // 40 | // // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. 41 | // 42 | // Such code is NOT meant to be used by a user directly, and is subject 43 | // to CHANGE WITHOUT NOTICE. Therefore DO NOT DEPEND ON IT in a user 44 | // program! 45 | 46 | #ifndef GTEST_INCLUDE_GTEST_GTEST_MESSAGE_H_ 47 | #define GTEST_INCLUDE_GTEST_GTEST_MESSAGE_H_ 48 | 49 | #include 50 | 51 | #include "gtest/internal/gtest-port.h" 52 | #include "gtest/internal/custom/raw-ostream.h" 53 | 54 | // Ensures that there is at least one operator<< in the global namespace. 55 | // See Message& operator<<(...) below for why. 56 | void operator<<(const testing::internal::Secret&, int); 57 | 58 | namespace testing { 59 | 60 | // The Message class works like an ostream repeater. 61 | // 62 | // Typical usage: 63 | // 64 | // 1. You stream a bunch of values to a Message object. 65 | // It will remember the text in a stringstream. 66 | // 2. Then you stream the Message object to an ostream. 67 | // This causes the text in the Message to be streamed 68 | // to the ostream. 69 | // 70 | // For example; 71 | // 72 | // testing::Message foo; 73 | // foo << 1 << " != " << 2; 74 | // std::cout << foo; 75 | // 76 | // will print "1 != 2". 77 | // 78 | // Message is not intended to be inherited from. In particular, its 79 | // destructor is not virtual. 80 | // 81 | // Note that stringstream behaves differently in gcc and in MSVC. You 82 | // can stream a NULL char pointer to it in the former, but not in the 83 | // latter (it causes an access violation if you do). The Message 84 | // class hides this difference by treating a NULL char pointer as 85 | // "(null)". 86 | class GTEST_API_ Message { 87 | private: 88 | // The type of basic IO manipulators (endl, ends, and flush) for 89 | // narrow streams. 90 | typedef std::ostream& (*BasicNarrowIoManip)(std::ostream&); 91 | 92 | public: 93 | // Constructs an empty Message. 94 | Message(); 95 | 96 | // Copy constructor. 97 | Message(const Message& msg) : ss_(new ::std::stringstream) { // NOLINT 98 | *ss_ << msg.GetString(); 99 | } 100 | 101 | // Constructs a Message from a C-string. 102 | explicit Message(const char* str) : ss_(new ::std::stringstream) { 103 | *ss_ << str; 104 | } 105 | 106 | #if GTEST_OS_SYMBIAN 107 | // Streams a value (either a pointer or not) to this object. 108 | template 109 | inline Message& operator <<(const T& value) { 110 | StreamHelper(typename internal::is_pointer::type(), value); 111 | return *this; 112 | } 113 | #else 114 | // Streams a non-pointer value to this object. 115 | template 116 | inline Message& operator <<(const T& val) { 117 | // Some libraries overload << for STL containers. These 118 | // overloads are defined in the global namespace instead of ::std. 119 | // 120 | // C++'s symbol lookup rule (i.e. Koenig lookup) says that these 121 | // overloads are visible in either the std namespace or the global 122 | // namespace, but not other namespaces, including the testing 123 | // namespace which Google Test's Message class is in. 124 | // 125 | // To allow STL containers (and other types that has a << operator 126 | // defined in the global namespace) to be used in Google Test 127 | // assertions, testing::Message must access the custom << operator 128 | // from the global namespace. With this using declaration, 129 | // overloads of << defined in the global namespace and those 130 | // visible via Koenig lookup are both exposed in this function. 131 | using ::operator <<; 132 | *ss_ << llvm_gtest::printable(val); 133 | return *this; 134 | } 135 | 136 | // Streams a pointer value to this object. 137 | // 138 | // This function is an overload of the previous one. When you 139 | // stream a pointer to a Message, this definition will be used as it 140 | // is more specialized. (The C++ Standard, section 141 | // [temp.func.order].) If you stream a non-pointer, then the 142 | // previous definition will be used. 143 | // 144 | // The reason for this overload is that streaming a NULL pointer to 145 | // ostream is undefined behavior. Depending on the compiler, you 146 | // may get "0", "(nil)", "(null)", or an access violation. To 147 | // ensure consistent result across compilers, we always treat NULL 148 | // as "(null)". 149 | template 150 | inline Message& operator <<(T* const& pointer) { // NOLINT 151 | if (pointer == NULL) { 152 | *ss_ << "(null)"; 153 | } else { 154 | *ss_ << llvm_gtest::printable(pointer); 155 | } 156 | return *this; 157 | } 158 | #endif // GTEST_OS_SYMBIAN 159 | 160 | // Since the basic IO manipulators are overloaded for both narrow 161 | // and wide streams, we have to provide this specialized definition 162 | // of operator <<, even though its body is the same as the 163 | // templatized version above. Without this definition, streaming 164 | // endl or other basic IO manipulators to Message will confuse the 165 | // compiler. 166 | Message& operator <<(BasicNarrowIoManip val) { 167 | *ss_ << val; 168 | return *this; 169 | } 170 | 171 | // Instead of 1/0, we want to see true/false for bool values. 172 | Message& operator <<(bool b) { 173 | return *this << (b ? "true" : "false"); 174 | } 175 | 176 | // These two overloads allow streaming a wide C string to a Message 177 | // using the UTF-8 encoding. 178 | Message& operator <<(const wchar_t* wide_c_str); 179 | Message& operator <<(wchar_t* wide_c_str); 180 | 181 | #if GTEST_HAS_STD_WSTRING 182 | // Converts the given wide string to a narrow string using the UTF-8 183 | // encoding, and streams the result to this Message object. 184 | Message& operator <<(const ::std::wstring& wstr); 185 | #endif // GTEST_HAS_STD_WSTRING 186 | 187 | #if GTEST_HAS_GLOBAL_WSTRING 188 | // Converts the given wide string to a narrow string using the UTF-8 189 | // encoding, and streams the result to this Message object. 190 | Message& operator <<(const ::wstring& wstr); 191 | #endif // GTEST_HAS_GLOBAL_WSTRING 192 | 193 | // Gets the text streamed to this object so far as an std::string. 194 | // Each '\0' character in the buffer is replaced with "\\0". 195 | // 196 | // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. 197 | std::string GetString() const; 198 | 199 | private: 200 | 201 | #if GTEST_OS_SYMBIAN 202 | // These are needed as the Nokia Symbian Compiler cannot decide between 203 | // const T& and const T* in a function template. The Nokia compiler _can_ 204 | // decide between class template specializations for T and T*, so a 205 | // tr1::type_traits-like is_pointer works, and we can overload on that. 206 | template 207 | inline void StreamHelper(internal::true_type /*is_pointer*/, T* pointer) { 208 | if (pointer == NULL) { 209 | *ss_ << "(null)"; 210 | } else { 211 | *ss_ << pointer; 212 | } 213 | } 214 | template 215 | inline void StreamHelper(internal::false_type /*is_pointer*/, 216 | const T& value) { 217 | // See the comments in Message& operator <<(const T&) above for why 218 | // we need this using statement. 219 | using ::operator <<; 220 | *ss_ << value; 221 | } 222 | #endif // GTEST_OS_SYMBIAN 223 | 224 | // We'll hold the text streamed to this object here. 225 | const internal::scoped_ptr< ::std::stringstream> ss_; 226 | 227 | // We declare (but don't implement) this to prevent the compiler 228 | // from implementing the assignment operator. 229 | void operator=(const Message&); 230 | }; 231 | 232 | // Streams a Message to an ostream. 233 | inline std::ostream& operator <<(std::ostream& os, const Message& sb) { 234 | return os << sb.GetString(); 235 | } 236 | 237 | namespace internal { 238 | 239 | // Converts a streamable value to an std::string. A NULL pointer is 240 | // converted to "(null)". When the input value is a ::string, 241 | // ::std::string, ::wstring, or ::std::wstring object, each NUL 242 | // character in it is replaced with "\\0". 243 | template 244 | std::string StreamableToString(const T& streamable) { 245 | return (Message() << streamable).GetString(); 246 | } 247 | 248 | } // namespace internal 249 | } // namespace testing 250 | 251 | #endif // GTEST_INCLUDE_GTEST_GTEST_MESSAGE_H_ 252 | --------------------------------------------------------------------------------