aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.travis.yml1
-rw-r--r--Changelog.md3
-rw-r--r--docs/grammar.txt23
-rw-r--r--docs/index.rst9
-rw-r--r--docs/layout-of-source-files.rst4
-rw-r--r--docs/miscellaneous.rst1
-rw-r--r--libevmasm/PeepholeOptimiser.cpp2
-rw-r--r--libsolidity/ast/AST.cpp3
-rw-r--r--libsolidity/codegen/ExpressionCompiler.cpp42
-rw-r--r--test/libsolidity/SolidityEndToEndTest.cpp22
10 files changed, 94 insertions, 16 deletions
diff --git a/.travis.yml b/.travis.yml
index 2160d175..820125cf 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -71,6 +71,7 @@ matrix:
dist: trusty
sudo: required
compiler: gcc
+ node_js: stable
services:
- docker
before_install:
diff --git a/Changelog.md b/Changelog.md
index 9faf0f8e..a82e8744 100644
--- a/Changelog.md
+++ b/Changelog.md
@@ -1,5 +1,8 @@
### 0.4.8 (unreleased)
+BugFixes:
+ * Type checker, code generator: enable access to events of base contracts' names.
+
### 0.4.7 (2016-12-15)
Features:
diff --git a/docs/grammar.txt b/docs/grammar.txt
index c9f7f448..b5d2b780 100644
--- a/docs/grammar.txt
+++ b/docs/grammar.txt
@@ -14,7 +14,7 @@ ContractDefinition = ( 'contract' | 'library' ) Identifier
ContractPart = StateVariableDeclaration | UsingForDeclaration
| StructDefinition | ModifierDefinition | FunctionDefinition | EventDefinition | EnumDefinition
-InheritanceSpecifier = Identifier ( '(' Expression ( ',' Expression )* ')' )?
+InheritanceSpecifier = UserDefinedTypeName ( '(' Expression ( ',' Expression )* ')' )?
StateVariableDeclaration = TypeName ( 'public' | 'internal' | 'private' )? Identifier ('=' Expression)? ';'
UsingForDeclaration = 'using' Identifier 'for' ('*' | TypeName) ';'
@@ -36,7 +36,15 @@ TypeNameList = '(' ( TypeName (',' TypeName )* )? ')'
// semantic restriction: mappings and structs (recursively) containing mappings
// are not allowed in argument lists
VariableDeclaration = TypeName Identifier
-TypeName = ElementaryTypeName | Identifier StorageLocation? | Mapping | ArrayTypeName | FunctionTypeName
+
+TypeName = ElementaryTypeName
+ | UserDefinedTypeName StorageLocation?
+ | Mapping
+ | ArrayTypeName
+ | FunctionTypeName
+
+UserDefinedTypeName = Identifier ( '.' Identifier )*
+
Mapping = 'mapping' '(' ElementaryTypeName '=>' TypeName ')'
ArrayTypeName = TypeName '[' Expression? ']' StorageLocation?
FunctionTypeName = 'function' TypeNameList ( 'internal' | 'external' | 'constant' | 'payable' )*
@@ -69,7 +77,7 @@ Expression =
| Expression '**' Expression
| Expression ('*' | '/' | '%') Expression
| Expression ('+' | '-') Expression
- | Expression ('<<' | '>>')
+ | Expression ('<<' | '>>') Expression
| Expression '&' Expression
| Expression '^' Expression
| Expression '|' Expression
@@ -82,7 +90,12 @@ Expression =
| Expression? (',' Expression)
| PrimaryExpression
-PrimaryExpression = Identifier | BooleanLiteral | NumberLiteral | HexLiteral | StringLiteral
+PrimaryExpression = Identifier
+ | BooleanLiteral
+ | NumberLiteral
+ | HexLiteral
+ | StringLiteral
+ | ElementaryTypeNameExpression
FunctionCall = ( PrimaryExpression | NewExpression | TypeName ) ( ( '.' Identifier ) | ( '[' Expression ']' ) )* '(' Expression? ( ',' Expression )* ')'
NewExpression = 'new' Identifier
@@ -100,6 +113,8 @@ Identifier = [a-zA-Z_] [a-zA-Z_0-9]*
HexNumber = '0x' [0-9a-fA-F]+
DecimalNumber = [0-9]+
+ElementaryTypeNameExpression = ElementaryTypeName
+
ElementaryTypeName = 'address' | 'bool' | 'string' | 'var'
| Int | Uint | Byte | Fixed | Ufixed
diff --git a/docs/index.rst b/docs/index.rst
index 9bee1515..cb79687b 100644
--- a/docs/index.rst
+++ b/docs/index.rst
@@ -87,6 +87,15 @@ Solidity Tools
* `evmdis <https://github.com/Arachnid/evmdis>`_
EVM Disassembler that performs static analysis on the bytecode to provide a higher level of abstraction than raw EVM operations.
+Third-Party Solidity Parsers and Grammars
+-----------------------------------------
+
+* `solidity-parser <https://github.com/ConsenSys/solidity-parser>`_
+ Solidity parser for JavaScript
+
+* `Solidity Grammar for ANTLR 4 <https://github.com/federicobond/solidity-antlr4>`_
+ Solidity grammar for the ANTLR 4 parser generator
+
Language Documentation
----------------------
diff --git a/docs/layout-of-source-files.rst b/docs/layout-of-source-files.rst
index 17ac8c6f..dff48be3 100644
--- a/docs/layout-of-source-files.rst
+++ b/docs/layout-of-source-files.rst
@@ -96,8 +96,8 @@ Use in Actual Compilers
When the compiler is invoked, it is not only possible to specify how to
discover the first element of a path, but it is possible to specify path prefix
remappings so that e.g. ``github.com/ethereum/dapp-bin/library`` is remapped to
-``/usr/local/dapp-bin/library`` and the compiler will read the files from there. If
-remapping keys are prefixes of each other, the longest is tried first. This
+``/usr/local/dapp-bin/library`` and the compiler will read the files from there.
+If multiple remappings can be applied, the one with the longest key is tried first. This
allows for a "fallback-remapping" with e.g. ``""`` maps to
``"/usr/local/include/solidity"``. Furthermore, these remappings can
depend on the context, which allows you to configure packages to
diff --git a/docs/miscellaneous.rst b/docs/miscellaneous.rst
index 4a9dad87..378c3c96 100644
--- a/docs/miscellaneous.rst
+++ b/docs/miscellaneous.rst
@@ -570,3 +570,4 @@ Language Grammar
================
.. literalinclude:: grammar.txt
+ :language: none
diff --git a/libevmasm/PeepholeOptimiser.cpp b/libevmasm/PeepholeOptimiser.cpp
index b96b0295..923ffa67 100644
--- a/libevmasm/PeepholeOptimiser.cpp
+++ b/libevmasm/PeepholeOptimiser.cpp
@@ -120,7 +120,7 @@ struct OpPop: SimplePeepholeOptimizerMethod<OpPop, 2>
if (instructionInfo(instr).ret == 1 && !instructionInfo(instr).sideEffects)
{
for (int j = 0; j < instructionInfo(instr).args; j++)
- *_out = Instruction::POP;
+ *_out = {Instruction::POP, _op.location()};
return true;
}
}
diff --git a/libsolidity/ast/AST.cpp b/libsolidity/ast/AST.cpp
index 3cd1dfbe..78d8949c 100644
--- a/libsolidity/ast/AST.cpp
+++ b/libsolidity/ast/AST.cpp
@@ -217,6 +217,9 @@ vector<Declaration const*> const& ContractDefinition::inheritableMembers() const
for (EnumDefinition const* e: definedEnums())
addInheritableMember(e);
+
+ for (EventDefinition const* e: events())
+ addInheritableMember(e);
}
return *m_inheritableMembers;
}
diff --git a/libsolidity/codegen/ExpressionCompiler.cpp b/libsolidity/codegen/ExpressionCompiler.cpp
index a7fb8408..3922da88 100644
--- a/libsolidity/codegen/ExpressionCompiler.cpp
+++ b/libsolidity/codegen/ExpressionCompiler.cpp
@@ -908,19 +908,43 @@ bool ExpressionCompiler::visit(MemberAccess const& _memberAccess)
solAssert(_memberAccess.annotation().type, "_memberAccess has no type");
if (auto funType = dynamic_cast<FunctionType const*>(_memberAccess.annotation().type.get()))
{
- if (funType->location() != FunctionType::Location::Internal)
- {
- _memberAccess.expression().accept(*this);
- m_context << funType->externalIdentifier();
- }
- else
+ switch (funType->location())
{
+ case FunctionType::Location::Internal:
// We do not visit the expression here on purpose, because in the case of an
// internal library function call, this would push the library address forcing
// us to link against it although we actually do not need it.
- auto const* function = dynamic_cast<FunctionDefinition const*>(_memberAccess.annotation().referencedDeclaration);
- solAssert(!!function, "Function not found in member access");
- utils().pushCombinedFunctionEntryLabel(*function);
+ if (auto const* function = dynamic_cast<FunctionDefinition const*>(_memberAccess.annotation().referencedDeclaration))
+ utils().pushCombinedFunctionEntryLabel(*function);
+ else
+ solAssert(false, "Function not found in member access");
+ break;
+ case FunctionType::Location::Event:
+ if (!dynamic_cast<EventDefinition const*>(_memberAccess.annotation().referencedDeclaration))
+ solAssert(false, "event not found");
+ // no-op, because the parent node will do the job
+ break;
+ case FunctionType::Location::External:
+ case FunctionType::Location::Creation:
+ case FunctionType::Location::DelegateCall:
+ case FunctionType::Location::CallCode:
+ case FunctionType::Location::Send:
+ case FunctionType::Location::Bare:
+ case FunctionType::Location::BareCallCode:
+ case FunctionType::Location::BareDelegateCall:
+ _memberAccess.expression().accept(*this);
+ m_context << funType->externalIdentifier();
+ break;
+ case FunctionType::Location::Log0:
+ case FunctionType::Location::Log1:
+ case FunctionType::Location::Log2:
+ case FunctionType::Location::Log3:
+ case FunctionType::Location::Log4:
+ case FunctionType::Location::ECRecover:
+ case FunctionType::Location::SHA256:
+ case FunctionType::Location::RIPEMD160:
+ default:
+ solAssert(false, "unsupported member function");
}
}
else if (dynamic_cast<TypeType const*>(_memberAccess.annotation().type.get()))
diff --git a/test/libsolidity/SolidityEndToEndTest.cpp b/test/libsolidity/SolidityEndToEndTest.cpp
index 94d4fb7f..d8539524 100644
--- a/test/libsolidity/SolidityEndToEndTest.cpp
+++ b/test/libsolidity/SolidityEndToEndTest.cpp
@@ -2770,6 +2770,28 @@ BOOST_AUTO_TEST_CASE(event_no_arguments)
BOOST_CHECK_EQUAL(m_logs[0].topics[0], dev::keccak256(string("Deposit()")));
}
+BOOST_AUTO_TEST_CASE(event_access_through_base_name)
+{
+ char const* sourceCode = R"(
+ contract A {
+ event x();
+ }
+ contract B is A {
+ function f() returns (uint) {
+ A.x();
+ return 1;
+ }
+ }
+ )";
+ compileAndRun(sourceCode);
+ callContractFunction("f()");
+ BOOST_REQUIRE_EQUAL(m_logs.size(), 1);
+ BOOST_CHECK_EQUAL(m_logs[0].address, m_contractAddress);
+ BOOST_CHECK(m_logs[0].data.empty());
+ BOOST_REQUIRE_EQUAL(m_logs[0].topics.size(), 1);
+ BOOST_CHECK_EQUAL(m_logs[0].topics[0], dev::keccak256(string("x()")));
+}
+
BOOST_AUTO_TEST_CASE(event_anonymous)
{
char const* sourceCode = R"(