Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,7 @@ add_subdirectory(libevmasm)
add_subdirectory(libyul)
add_subdirectory(libsolidity)
add_subdirectory(libsolc)
add_subdirectory(libstdlib)
add_subdirectory(tools)

if (NOT EMSCRIPTEN)
Expand Down
12 changes: 12 additions & 0 deletions libsolidity/interface/CompilerStack.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,8 @@
#include <libsolidity/codegen/ir/Common.h>
#include <libsolidity/codegen/ir/IRGenerator.h>

#include <libstdlib/stdlib.h>

#include <libyul/YulString.h>
#include <libyul/AsmPrinter.h>
#include <libyul/AsmJsonConverter.h>
Expand Down Expand Up @@ -95,6 +97,7 @@ using namespace std;
using namespace solidity;
using namespace solidity::langutil;
using namespace solidity::frontend;
using namespace solidity::stdlib;

using solidity::util::errinfo_comment;

Expand Down Expand Up @@ -369,6 +372,15 @@ bool CompilerStack::parse()
for (auto const& import: ASTNode::filteredNodes<ImportDirective>(source.ast->nodes()))
{
solAssert(!import->path().empty(), "Import path cannot be empty.");
// Check whether the import directive is for the standard library,
// and if yes, add specified file to source units to be parsed.
auto it = stdlib::sources.find(import->path());
if (it != stdlib::sources.end())
{
auto [name, content] = *it;
m_sources[name].charStream = make_unique<CharStream>(content, name);
sourcesToParse.push_back(name);
}

// The current value of `path` is the absolute path as seen from this source file.
// We first have to apply remappings before we can store the actual absolute path
Expand Down
29 changes: 25 additions & 4 deletions libsolidity/parsing/Parser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -271,9 +271,9 @@ ASTPointer<ImportDirective> Parser::parseImportDirective()
SourceLocation unitAliasLocation{};
ImportDirective::SymbolAliasList symbolAliases;

if (m_scanner->currentToken() == Token::StringLiteral)
if (isQuotedPath() || isStdlibPath())
{
path = getLiteralAndAdvance();
path = isQuotedPath() ? getLiteralAndAdvance() : getStdlibImportPathAndAdvance();
if (m_scanner->currentToken() == Token::As)
{
advance();
Expand Down Expand Up @@ -315,9 +315,9 @@ ASTPointer<ImportDirective> Parser::parseImportDirective()
if (m_scanner->currentToken() != Token::Identifier || m_scanner->currentLiteral() != "from")
fatalParserError(8208_error, "Expected \"from\".");
advance();
if (m_scanner->currentToken() != Token::StringLiteral)
if (!isQuotedPath() && !isStdlibPath())
fatalParserError(6845_error, "Expected import path.");
path = getLiteralAndAdvance();
path = isQuotedPath() ? getLiteralAndAdvance() : getStdlibImportPathAndAdvance();
}
if (path->empty())
fatalParserError(6326_error, "Import path cannot be empty.");
Expand Down Expand Up @@ -2486,4 +2486,25 @@ ASTPointer<ASTString> Parser::getLiteralAndAdvance()
return identifier;
}

bool Parser::isQuotedPath() const
{
return m_scanner->currentToken() == Token::StringLiteral;
}

bool Parser::isStdlibPath() const
{
return m_experimentalSolidityEnabledInCurrentSourceUnit
&& m_scanner->currentToken() == Token::Identifier
&& m_scanner->currentLiteral() == "std";
}

ASTPointer<ASTString> Parser::getStdlibImportPathAndAdvance()
{
ASTPointer<ASTString> std = expectIdentifierToken();
if (m_scanner->currentToken() == Token::Period)
advance();
ASTPointer<ASTString> library = expectIdentifierToken();
return make_shared<ASTString>(*std + "." + *library);
}

}
5 changes: 5 additions & 0 deletions libsolidity/parsing/Parser.h
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,11 @@ class Parser: public langutil::ParserBase
ASTPointer<ASTString> getLiteralAndAdvance();
///@}

bool isQuotedPath() const;
bool isStdlibPath() const;

ASTPointer<ASTString> getStdlibImportPathAndAdvance();

/// Creates an empty ParameterList at the current location (used if parameters can be omitted).
ASTPointer<ParameterList> createEmptyParameterList();

Expand Down
18 changes: 18 additions & 0 deletions libstdlib/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# This will re-generate the headers if any file within src was modified.
set_directory_properties(PROPERTY CMAKE_CONFIGURE_DEPENDS ${CMAKE_SOURCE_DIR}/stdlib/src/)

set(STDLIB stub)
set(GENERATED_STDLIB_HEADERS)
foreach(src IN LISTS STDLIB)
set(STDLIB_FILE ${CMAKE_SOURCE_DIR}/libstdlib/src/${src}.sol)
file(READ ${STDLIB_FILE} STDLIB_FILE_CONTENT HEX)
string(REGEX MATCHALL ".." STDLIB_FILE_CONTENT "${STDLIB_FILE_CONTENT}")
list(REMOVE_ITEM STDLIB_FILE_CONTENT "0d")
string(REGEX REPLACE ";" ",\n\t0x" STDLIB_FILE_CONTENT "${STDLIB_FILE_CONTENT}")
set(STDLIB_FILE_CONTENT "0x${STDLIB_FILE_CONTENT}")
set(STDLIB_FILE_NAME ${src})
configure_file("${CMAKE_SOURCE_DIR}/libstdlib/stdlib.src.h.in" ${CMAKE_BINARY_DIR}/include/libstdlib/${src}.h NEWLINE_STYLE LF @ONLY)
list(APPEND GENERATED_STDLIB_HEADERS ${CMAKE_BINARY_DIR}/include/libstdlib/${src}.h)
endforeach()

configure_file("${CMAKE_SOURCE_DIR}/libstdlib/stdlib.h.in" ${CMAKE_BINARY_DIR}/include/libstdlib/stdlib.h NEWLINE_STYLE LF @ONLY)
9 changes: 9 additions & 0 deletions libstdlib/src/stub.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// SPDX-License-Identifier: Apache-2.0
pragma solidity >=0.0;

pragma experimental solidity;

function identity(uint256 x) pure returns (uint256)
{
return x;
}
15 changes: 15 additions & 0 deletions libstdlib/stdlib.h.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#pragma once

#include <map>
#include <string>

#include "libstdlib/stub.h"

namespace solidity::stdlib
{

static std::map<std::string, std::string> sources = {
{ "std.stub", stub }
};

} // namespace solidity::stdlib
13 changes: 13 additions & 0 deletions libstdlib/stdlib.src.h.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// The generation of this file is defined in stdlib/CMakeLists.txt.
// This file was generated by using the content of stdlib/src/@STDLIB_FILE_NAME@.sol.

#pragma once

namespace solidity::stdlib
{

static char const @STDLIB_FILE_NAME@[] = {
@STDLIB_FILE_CONTENT@, 0
};

} // namespace solidity::stdlib
2 changes: 1 addition & 1 deletion scripts/ASTImportTest.sh
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,7 @@ esac
# boost_filesystem_bug specifically tests a local fix for a boost::filesystem
# bug. Since the test involves a malformed path, there is no point in running
# tests on it. See https://github.com/boostorg/filesystem/issues/176
IMPORT_TEST_FILES=$(find "${TEST_DIRS[@]}" -name "*.sol" -and -not -name "boost_filesystem_bug.sol")
IMPORT_TEST_FILES=$(find "${TEST_DIRS[@]}" -name "*.sol" -and -not -name "boost_filesystem_bug.sol" -not -path "*/experimental/*")

NSOURCES="$(echo "${IMPORT_TEST_FILES}" | wc -l)"
echo "Looking at ${NSOURCES} .sol files..."
Expand Down
2 changes: 1 addition & 1 deletion scripts/test_antlr_grammar.sh
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ do
SOL_FILES+=("$line")
done < <(
grep --include "*.sol" -riL -E \
"^\/\/ (Syntax|Type|Declaration)Error|^\/\/ ParserError (1684|2837|3716|3997|5333|6275|6281|6933|7319|8185|7637)|^==== Source:" \
"^\/\/ (Syntax|Type|Declaration)Error|^\/\/ ParserError (1684|2837|3716|3997|5333|6275|6281|6933|7319|8185|7637)|^==== Source:|^pragma experimental solidity;" \
"${ROOT_DIR}/test/libsolidity/syntaxTests" \
"${ROOT_DIR}/test/libsolidity/semanticTests" |
# Skipping the unicode tests as I couldn't adapt the lexical grammar to recursively counting RLO/LRO/PDF's.
Expand Down
35 changes: 19 additions & 16 deletions test/libsolidity/SyntaxTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -123,25 +123,28 @@ void SyntaxTest::filterObtainedErrors()
string sourceName;
if (SourceLocation const* location = currentError->sourceLocation())
{
locationStart = location->start;
locationEnd = location->end;
solAssert(location->sourceName, "");
sourceName = *location->sourceName;
solAssert(m_sources.sources.count(sourceName) == 1, "");

int preambleSize =
static_cast<int>(compiler().charStream(sourceName).size()) -
static_cast<int>(m_sources.sources[sourceName].size());
solAssert(preambleSize >= 0, "");

// ignore the version & license pragma inserted by the testing tool when calculating locations.
if (location->start != -1)
{
solAssert(location->start >= preambleSize, "");
locationStart = location->start - preambleSize;
}
if (location->end != -1)
if(m_sources.sources.count(sourceName) == 1)
{
solAssert(location->end >= preambleSize, "");
locationEnd = location->end - preambleSize;
int preambleSize =
static_cast<int>(compiler().charStream(sourceName).size()) -
static_cast<int>(m_sources.sources[sourceName].size());
solAssert(preambleSize >= 0, "");

// ignore the version & license pragma inserted by the testing tool when calculating locations.
if (location->start != -1)
{
solAssert(location->start >= preambleSize, "");
locationStart = location->start - preambleSize;
}
if (location->end != -1)
{
solAssert(location->end >= preambleSize, "");
locationEnd = location->end - preambleSize;
}
}
}
m_errorList.emplace_back(SyntaxTestError{
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
pragma experimental solidity;

import std.stub;
// ====
// EVMVersion: >=constantinople
// ----
// Warning 2264: (std.stub:63-92): Experimental features are turned on. Do not use experimental features on live deployments.
// Warning 2264: (0-29): Experimental features are turned on. Do not use experimental features on live deployments.
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
pragma experimental solidity;

import std.stub as stub;
// ====
// EVMVersion: >=constantinople
// ----
// Warning 2264: (std.stub:63-92): Experimental features are turned on. Do not use experimental features on live deployments.
// Warning 2264: (0-29): Experimental features are turned on. Do not use experimental features on live deployments.
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
pragma experimental solidity;

import { identity } from std.stub;
// ====
// EVMVersion: >=constantinople
// ----
// Warning 2264: (std.stub:63-92): Experimental features are turned on. Do not use experimental features on live deployments.
// Warning 2264: (0-29): Experimental features are turned on. Do not use experimental features on live deployments.
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
pragma experimental solidity;

import * as stub from std.stub;
// ====
// EVMVersion: >=constantinople
// ----
// Warning 2264: (std.stub:63-92): Experimental features are turned on. Do not use experimental features on live deployments.
// Warning 2264: (0-29): Experimental features are turned on. Do not use experimental features on live deployments.
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import std.stub;
// ----
// ParserError 9478: (7-10): Expected string literal (path), "*" or alias list.
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import { identity } from std.stub;
// ----
// ParserError 6845: (25-28): Expected import path.