1 /*
2 	This file is part of solidity.
3 
4 	solidity is free software: you can redistribute it and/or modify
5 	it under the terms of the GNU General Public License as published by
6 	the Free Software Foundation, either version 3 of the License, or
7 	(at your option) any later version.
8 
9 	solidity is distributed in the hope that it will be useful,
10 	but WITHOUT ANY WARRANTY; without even the implied warranty of
11 	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 	GNU General Public License for more details.
13 
14 	You should have received a copy of the GNU General Public License
15 	along with solidity.  If not, see <http://www.gnu.org/licenses/>.
16 */
17 // SPDX-License-Identifier: GPL-3.0
18 /**
19  * @author Christian <c@ethdev.com>
20  * @date 2014
21  * Solidity abstract syntax tree.
22  */
23 
24 #include <libsolidity/ast/AST.h>
25 
26 #include <libsolidity/ast/CallGraph.h>
27 #include <libsolidity/ast/ASTVisitor.h>
28 #include <libsolidity/ast/AST_accept.h>
29 #include <libsolidity/ast/TypeProvider.h>
30 #include <libsolutil/Keccak256.h>
31 
32 #include <boost/algorithm/string.hpp>
33 
34 #include <functional>
35 #include <utility>
36 
37 using namespace std;
38 using namespace solidity;
39 using namespace solidity::frontend;
40 
ASTNode(int64_t _id,SourceLocation _location)41 ASTNode::ASTNode(int64_t _id, SourceLocation _location):
42 	m_id(static_cast<size_t>(_id)),
43 	m_location(std::move(_location))
44 {
45 }
46 
referencedDeclaration(Expression const & _expression)47 Declaration const* ASTNode::referencedDeclaration(Expression const& _expression)
48 {
49 	if (auto const* memberAccess = dynamic_cast<MemberAccess const*>(&_expression))
50 		return memberAccess->annotation().referencedDeclaration;
51 	else if (auto const* identifierPath = dynamic_cast<IdentifierPath const*>(&_expression))
52 		return identifierPath->annotation().referencedDeclaration;
53 	else if (auto const* identifier = dynamic_cast<Identifier const*>(&_expression))
54 		return identifier->annotation().referencedDeclaration;
55 	else
56 		return nullptr;
57 }
58 
resolveFunctionCall(FunctionCall const & _functionCall,ContractDefinition const * _mostDerivedContract)59 FunctionDefinition const* ASTNode::resolveFunctionCall(FunctionCall const& _functionCall, ContractDefinition const* _mostDerivedContract)
60 {
61 	auto const* functionDef = dynamic_cast<FunctionDefinition const*>(
62 		ASTNode::referencedDeclaration(_functionCall.expression())
63 	);
64 
65 	if (!functionDef)
66 		return nullptr;
67 
68 	if (auto const* memberAccess = dynamic_cast<MemberAccess const*>(&_functionCall.expression()))
69 	{
70 		if (*memberAccess->annotation().requiredLookup == VirtualLookup::Super)
71 		{
72 			if (auto const typeType = dynamic_cast<TypeType const*>(memberAccess->expression().annotation().type))
73 				if (auto const contractType = dynamic_cast<ContractType const*>(typeType->actualType()))
74 				{
75 					solAssert(_mostDerivedContract, "");
76 					solAssert(contractType->isSuper(), "");
77 					ContractDefinition const* superContract = contractType->contractDefinition().superContract(*_mostDerivedContract);
78 
79 					return &functionDef->resolveVirtual(
80 						*_mostDerivedContract,
81 						superContract
82 					);
83 				}
84 		}
85 		else
86 			solAssert(*memberAccess->annotation().requiredLookup == VirtualLookup::Static, "");
87 	}
88 	else if (auto const* identifier = dynamic_cast<Identifier const*>(&_functionCall.expression()))
89 	{
90 		solAssert(*identifier->annotation().requiredLookup == VirtualLookup::Virtual, "");
91 		if (functionDef->virtualSemantics())
92 		{
93 			solAssert(_mostDerivedContract, "");
94 			return &functionDef->resolveVirtual(*_mostDerivedContract);
95 		}
96 	}
97 	else
98 		solAssert(false, "");
99 
100 	return functionDef;
101 }
102 
annotation() const103 ASTAnnotation& ASTNode::annotation() const
104 {
105 	if (!m_annotation)
106 		m_annotation = make_unique<ASTAnnotation>();
107 	return *m_annotation;
108 }
109 
annotation() const110 SourceUnitAnnotation& SourceUnit::annotation() const
111 {
112 	return initAnnotation<SourceUnitAnnotation>();
113 }
114 
referencedSourceUnits(bool _recurse,set<SourceUnit const * > _skipList) const115 set<SourceUnit const*> SourceUnit::referencedSourceUnits(bool _recurse, set<SourceUnit const*> _skipList) const
116 {
117 	set<SourceUnit const*> sourceUnits;
118 	for (ImportDirective const* importDirective: filteredNodes<ImportDirective>(nodes()))
119 	{
120 		auto const& sourceUnit = importDirective->annotation().sourceUnit;
121 		if (!_skipList.count(sourceUnit))
122 		{
123 			_skipList.insert(sourceUnit);
124 			sourceUnits.insert(sourceUnit);
125 			if (_recurse)
126 				sourceUnits += sourceUnit->referencedSourceUnits(true, _skipList);
127 		}
128 	}
129 	return sourceUnits;
130 }
131 
annotation() const132 ImportAnnotation& ImportDirective::annotation() const
133 {
134 	return initAnnotation<ImportAnnotation>();
135 }
136 
type() const137 Type const* ImportDirective::type() const
138 {
139 	solAssert(!!annotation().sourceUnit, "");
140 	return TypeProvider::module(*annotation().sourceUnit);
141 }
142 
derivesFrom(ContractDefinition const & _base) const143 bool ContractDefinition::derivesFrom(ContractDefinition const& _base) const
144 {
145 	return util::contains(annotation().linearizedBaseContracts, &_base);
146 }
147 
interfaceFunctions(bool _includeInheritedFunctions) const148 map<util::FixedHash<4>, FunctionTypePointer> ContractDefinition::interfaceFunctions(bool _includeInheritedFunctions) const
149 {
150 	auto exportedFunctionList = interfaceFunctionList(_includeInheritedFunctions);
151 
152 	map<util::FixedHash<4>, FunctionTypePointer> exportedFunctions;
153 	for (auto const& it: exportedFunctionList)
154 		exportedFunctions.insert(it);
155 
156 	solAssert(
157 		exportedFunctionList.size() == exportedFunctions.size(),
158 		"Hash collision at Function Definition Hash calculation"
159 	);
160 
161 	return exportedFunctions;
162 }
163 
constructor() const164 FunctionDefinition const* ContractDefinition::constructor() const
165 {
166 	for (FunctionDefinition const* f: definedFunctions())
167 		if (f->isConstructor())
168 			return f;
169 	return nullptr;
170 }
171 
canBeDeployed() const172 bool ContractDefinition::canBeDeployed() const
173 {
174 	return !abstract() && !isInterface();
175 }
176 
fallbackFunction() const177 FunctionDefinition const* ContractDefinition::fallbackFunction() const
178 {
179 	for (ContractDefinition const* contract: annotation().linearizedBaseContracts)
180 		for (FunctionDefinition const* f: contract->definedFunctions())
181 			if (f->isFallback())
182 				return f;
183 	return nullptr;
184 }
185 
receiveFunction() const186 FunctionDefinition const* ContractDefinition::receiveFunction() const
187 {
188 	for (ContractDefinition const* contract: annotation().linearizedBaseContracts)
189 		for (FunctionDefinition const* f: contract->definedFunctions())
190 			if (f->isReceive())
191 				return f;
192 	return nullptr;
193 }
194 
interfaceEvents() const195 vector<EventDefinition const*> const& ContractDefinition::interfaceEvents() const
196 {
197 	return m_interfaceEvents.init([&]{
198 		set<string> eventsSeen;
199 		vector<EventDefinition const*> interfaceEvents;
200 
201 		for (ContractDefinition const* contract: annotation().linearizedBaseContracts)
202 			for (EventDefinition const* e: contract->events())
203 			{
204 				/// NOTE: this requires the "internal" version of an Event,
205 				///       though here internal strictly refers to visibility,
206 				///       and not to function encoding (jump vs. call)
207 				auto const& function = e->functionType(true);
208 				solAssert(function, "");
209 				string eventSignature = function->externalSignature();
210 				if (eventsSeen.count(eventSignature) == 0)
211 				{
212 					eventsSeen.insert(eventSignature);
213 					interfaceEvents.push_back(e);
214 				}
215 			}
216 
217 		return interfaceEvents;
218 	});
219 }
220 
interfaceErrors(bool _requireCallGraph) const221 vector<ErrorDefinition const*> ContractDefinition::interfaceErrors(bool _requireCallGraph) const
222 {
223 	set<ErrorDefinition const*, CompareByID> result;
224 	for (ContractDefinition const* contract: annotation().linearizedBaseContracts)
225 		result += filteredNodes<ErrorDefinition>(contract->m_subNodes);
226 	solAssert(annotation().creationCallGraph.set() == annotation().deployedCallGraph.set(), "");
227 	if (_requireCallGraph)
228 		solAssert(annotation().creationCallGraph.set(), "");
229 	if (annotation().creationCallGraph.set())
230 	{
231 		result += (*annotation().creationCallGraph)->usedErrors;
232 		result += (*annotation().deployedCallGraph)->usedErrors;
233 	}
234 	return convertContainer<vector<ErrorDefinition const*>>(move(result));
235 }
236 
interfaceFunctionList(bool _includeInheritedFunctions) const237 vector<pair<util::FixedHash<4>, FunctionTypePointer>> const& ContractDefinition::interfaceFunctionList(bool _includeInheritedFunctions) const
238 {
239 	return m_interfaceFunctionList[_includeInheritedFunctions].init([&]{
240 		set<string> signaturesSeen;
241 		vector<pair<util::FixedHash<4>, FunctionTypePointer>> interfaceFunctionList;
242 
243 		for (ContractDefinition const* contract: annotation().linearizedBaseContracts)
244 		{
245 			if (_includeInheritedFunctions == false && contract != this)
246 				continue;
247 			vector<FunctionTypePointer> functions;
248 			for (FunctionDefinition const* f: contract->definedFunctions())
249 				if (f->isPartOfExternalInterface())
250 					functions.push_back(TypeProvider::function(*f, FunctionType::Kind::External));
251 			for (VariableDeclaration const* v: contract->stateVariables())
252 				if (v->isPartOfExternalInterface())
253 					functions.push_back(TypeProvider::function(*v));
254 			for (FunctionTypePointer const& fun: functions)
255 			{
256 				if (!fun->interfaceFunctionType())
257 					// Fails hopefully because we already registered the error
258 					continue;
259 				string functionSignature = fun->externalSignature();
260 				if (signaturesSeen.count(functionSignature) == 0)
261 				{
262 					signaturesSeen.insert(functionSignature);
263 					util::FixedHash<4> hash(util::keccak256(functionSignature));
264 					interfaceFunctionList.emplace_back(hash, fun);
265 				}
266 			}
267 		}
268 
269 		return interfaceFunctionList;
270 	});
271 }
272 
interfaceId() const273 uint32_t ContractDefinition::interfaceId() const
274 {
275 	uint32_t result{0};
276 	for (auto const& function: interfaceFunctionList(false))
277 		result ^= fromBigEndian<uint32_t>(function.first.ref());
278 	return result;
279 }
280 
type() const281 Type const* ContractDefinition::type() const
282 {
283 	return TypeProvider::typeType(TypeProvider::contract(*this));
284 }
285 
annotation() const286 ContractDefinitionAnnotation& ContractDefinition::annotation() const
287 {
288 	return initAnnotation<ContractDefinitionAnnotation>();
289 }
290 
superContract(ContractDefinition const & _mostDerivedContract) const291 ContractDefinition const* ContractDefinition::superContract(ContractDefinition const& _mostDerivedContract) const
292 {
293 	auto const& hierarchy = _mostDerivedContract.annotation().linearizedBaseContracts;
294 	auto it = find(hierarchy.begin(), hierarchy.end(), this);
295 	solAssert(it != hierarchy.end(), "Base not found in inheritance hierarchy.");
296 	++it;
297 	if (it == hierarchy.end())
298 		return nullptr;
299 	else
300 	{
301 		solAssert(*it != this, "");
302 		return *it;
303 	}
304 }
305 
nextConstructor(ContractDefinition const & _mostDerivedContract) const306 FunctionDefinition const* ContractDefinition::nextConstructor(ContractDefinition const& _mostDerivedContract) const
307 {
308 	ContractDefinition const* next = superContract(_mostDerivedContract);
309 	if (next == nullptr)
310 		return nullptr;
311 	for (ContractDefinition const* c: _mostDerivedContract.annotation().linearizedBaseContracts)
312 		if (c == next || next == nullptr)
313 		{
314 			if (c->constructor())
315 				return c->constructor();
316 			next = nullptr;
317 		}
318 
319 	return nullptr;
320 }
321 
definedFunctionsByName() const322 multimap<std::string, FunctionDefinition const*> const& ContractDefinition::definedFunctionsByName() const
323 {
324 	return m_definedFunctionsByName.init([&]{
325 		std::multimap<std::string, FunctionDefinition const*> result;
326 		for (FunctionDefinition const* fun: filteredNodes<FunctionDefinition>(m_subNodes))
327 			result.insert({fun->name(), fun});
328 		return result;
329 	});
330 }
331 
332 
annotation() const333 TypeNameAnnotation& TypeName::annotation() const
334 {
335 	return initAnnotation<TypeNameAnnotation>();
336 }
337 
type() const338 Type const* UserDefinedValueTypeDefinition::type() const
339 {
340 	solAssert(m_underlyingType->annotation().type, "");
341 	return TypeProvider::typeType(TypeProvider::userDefinedValueType(*this));
342 }
343 
annotation() const344 TypeDeclarationAnnotation& UserDefinedValueTypeDefinition::annotation() const
345 {
346 	return initAnnotation<TypeDeclarationAnnotation>();
347 }
348 
type() const349 Type const* StructDefinition::type() const
350 {
351 	solAssert(annotation().recursive.has_value(), "Requested struct type before DeclarationTypeChecker.");
352 	return TypeProvider::typeType(TypeProvider::structType(*this, DataLocation::Storage));
353 }
354 
annotation() const355 StructDeclarationAnnotation& StructDefinition::annotation() const
356 {
357 	return initAnnotation<StructDeclarationAnnotation>();
358 }
359 
type() const360 Type const* EnumValue::type() const
361 {
362 	auto parentDef = dynamic_cast<EnumDefinition const*>(scope());
363 	solAssert(parentDef, "Enclosing Scope of EnumValue was not set");
364 	return TypeProvider::enumType(*parentDef);
365 }
366 
type() const367 Type const* EnumDefinition::type() const
368 {
369 	return TypeProvider::typeType(TypeProvider::enumType(*this));
370 }
371 
annotation() const372 TypeDeclarationAnnotation& EnumDefinition::annotation() const
373 {
374 	return initAnnotation<TypeDeclarationAnnotation>();
375 }
376 
libraryFunction() const377 bool FunctionDefinition::libraryFunction() const
378 {
379 	if (auto const* contractDef = dynamic_cast<ContractDefinition const*>(scope()))
380 		return contractDef->isLibrary();
381 	return false;
382 }
383 
defaultVisibility() const384 Visibility FunctionDefinition::defaultVisibility() const
385 {
386 	solAssert(!isConstructor(), "");
387 	return isFree() ? Visibility::Internal : Declaration::defaultVisibility();
388 }
389 
functionType(bool _internal) const390 FunctionTypePointer FunctionDefinition::functionType(bool _internal) const
391 {
392 	if (_internal)
393 	{
394 		switch (visibility())
395 		{
396 		case Visibility::Default:
397 			solAssert(false, "visibility() should not return Default");
398 		case Visibility::Private:
399 		case Visibility::Internal:
400 		case Visibility::Public:
401 			return TypeProvider::function(*this, FunctionType::Kind::Internal);
402 		case Visibility::External:
403 			return {};
404 		}
405 	}
406 	else
407 	{
408 		switch (visibility())
409 		{
410 		case Visibility::Default:
411 			solAssert(false, "visibility() should not return Default");
412 		case Visibility::Private:
413 		case Visibility::Internal:
414 			return {};
415 		case Visibility::Public:
416 		case Visibility::External:
417 			return TypeProvider::function(*this, FunctionType::Kind::External);
418 		}
419 	}
420 
421 	// To make the compiler happy
422 	return {};
423 }
424 
type() const425 Type const* FunctionDefinition::type() const
426 {
427 	solAssert(visibility() != Visibility::External, "");
428 	return TypeProvider::function(*this, FunctionType::Kind::Internal);
429 }
430 
typeViaContractName() const431 Type const* FunctionDefinition::typeViaContractName() const
432 {
433 	if (libraryFunction())
434 	{
435 		if (isPublic())
436 			return FunctionType(*this).asExternallyCallableFunction(true);
437 		else
438 			return TypeProvider::function(*this, FunctionType::Kind::Internal);
439 	}
440 	else
441 		return TypeProvider::function(*this, FunctionType::Kind::Declaration);
442 }
443 
externalSignature() const444 string FunctionDefinition::externalSignature() const
445 {
446 	return TypeProvider::function(*this)->externalSignature();
447 }
448 
externalIdentifierHex() const449 string FunctionDefinition::externalIdentifierHex() const
450 {
451 	return TypeProvider::function(*this)->externalIdentifierHex();
452 }
453 
annotation() const454 FunctionDefinitionAnnotation& FunctionDefinition::annotation() const
455 {
456 	return initAnnotation<FunctionDefinitionAnnotation>();
457 }
458 
resolveVirtual(ContractDefinition const & _mostDerivedContract,ContractDefinition const * _searchStart) const459 FunctionDefinition const& FunctionDefinition::resolveVirtual(
460 	ContractDefinition const& _mostDerivedContract,
461 	ContractDefinition const* _searchStart
462 ) const
463 {
464 	solAssert(!isConstructor(), "");
465 	solAssert(!name().empty(), "");
466 
467 	// If we are not doing super-lookup and the function is not virtual, we can stop here.
468 	if (_searchStart == nullptr && !virtualSemantics())
469 		return *this;
470 
471 	solAssert(!isFree(), "");
472 	solAssert(isOrdinary(), "");
473 	solAssert(!libraryFunction(), "");
474 
475 	FunctionType const* functionType = TypeProvider::function(*this)->asExternallyCallableFunction(false);
476 
477 	bool foundSearchStart = (_searchStart == nullptr);
478 	for (ContractDefinition const* c: _mostDerivedContract.annotation().linearizedBaseContracts)
479 	{
480 		if (!foundSearchStart && c != _searchStart)
481 			continue;
482 		else
483 			foundSearchStart = true;
484 
485 		for (FunctionDefinition const* function: c->definedFunctions(name()))
486 			if (
487 				// With super lookup analysis guarantees that there is an implemented function in the chain.
488 				// With virtual lookup there are valid cases where returning an unimplemented one is fine.
489 				(function->isImplemented() || _searchStart == nullptr) &&
490 				FunctionType(*function).asExternallyCallableFunction(false)->hasEqualParameterTypes(*functionType)
491 			)
492 				return *function;
493 	}
494 
495 	solAssert(false, "Virtual function " + name() + " not found.");
496 	return *this; // not reached
497 }
498 
type() const499 Type const* ModifierDefinition::type() const
500 {
501 	return TypeProvider::modifier(*this);
502 }
503 
annotation() const504 ModifierDefinitionAnnotation& ModifierDefinition::annotation() const
505 {
506 	return initAnnotation<ModifierDefinitionAnnotation>();
507 }
508 
resolveVirtual(ContractDefinition const & _mostDerivedContract,ContractDefinition const * _searchStart) const509 ModifierDefinition const& ModifierDefinition::resolveVirtual(
510 	ContractDefinition const& _mostDerivedContract,
511 	ContractDefinition const* _searchStart
512 ) const
513 {
514 	solAssert(_searchStart == nullptr, "Used super in connection with modifiers.");
515 
516 	// If we are not doing super-lookup and the modifier is not virtual, we can stop here.
517 	if (_searchStart == nullptr && !virtualSemantics())
518 		return *this;
519 
520 	solAssert(!dynamic_cast<ContractDefinition const&>(*scope()).isLibrary(), "");
521 
522 	for (ContractDefinition const* c: _mostDerivedContract.annotation().linearizedBaseContracts)
523 	{
524 		if (_searchStart != nullptr && c != _searchStart)
525 			continue;
526 		_searchStart = nullptr;
527 		for (ModifierDefinition const* modifier: c->functionModifiers())
528 			if (modifier->name() == name())
529 				return *modifier;
530 	}
531 	solAssert(false, "Virtual modifier " + name() + " not found.");
532 	return *this; // not reached
533 }
534 
535 
type() const536 Type const* EventDefinition::type() const
537 {
538 	return TypeProvider::function(*this);
539 }
540 
functionType(bool _internal) const541 FunctionTypePointer EventDefinition::functionType(bool _internal) const
542 {
543 	if (_internal)
544 		return TypeProvider::function(*this);
545 	else
546 		return nullptr;
547 }
548 
annotation() const549 EventDefinitionAnnotation& EventDefinition::annotation() const
550 {
551 	return initAnnotation<EventDefinitionAnnotation>();
552 }
553 
type() const554 Type const* ErrorDefinition::type() const
555 {
556 	return TypeProvider::function(*this);
557 }
558 
functionType(bool _internal) const559 FunctionTypePointer ErrorDefinition::functionType(bool _internal) const
560 {
561 	if (_internal)
562 		return TypeProvider::function(*this);
563 	else
564 		return nullptr;
565 }
566 
annotation() const567 ErrorDefinitionAnnotation& ErrorDefinition::annotation() const
568 {
569 	return initAnnotation<ErrorDefinitionAnnotation>();
570 }
571 
sourceUnit() const572 SourceUnit const& Scopable::sourceUnit() const
573 {
574 	ASTNode const* s = scope();
575 	solAssert(s, "");
576 	// will not always be a declaration
577 	while (dynamic_cast<Scopable const*>(s) && dynamic_cast<Scopable const*>(s)->scope())
578 		s = dynamic_cast<Scopable const*>(s)->scope();
579 	return dynamic_cast<SourceUnit const&>(*s);
580 }
581 
functionOrModifierDefinition() const582 CallableDeclaration const* Scopable::functionOrModifierDefinition() const
583 {
584 	ASTNode const* s = scope();
585 	solAssert(s, "");
586 	while (dynamic_cast<Scopable const*>(s))
587 	{
588 		if (auto funDef = dynamic_cast<FunctionDefinition const*>(s))
589 			return funDef;
590 		if (auto modDef = dynamic_cast<ModifierDefinition const*>(s))
591 			return modDef;
592 		s = dynamic_cast<Scopable const*>(s)->scope();
593 	}
594 	return nullptr;
595 }
596 
sourceUnitName() const597 string Scopable::sourceUnitName() const
598 {
599 	return *sourceUnit().annotation().path;
600 }
601 
isEnumValue() const602 bool Declaration::isEnumValue() const
603 {
604 	solAssert(scope(), "");
605 	return dynamic_cast<EnumDefinition const*>(scope());
606 }
607 
isStructMember() const608 bool Declaration::isStructMember() const
609 {
610 	solAssert(scope(), "");
611 	return dynamic_cast<StructDefinition const*>(scope());
612 }
613 
isEventOrErrorParameter() const614 bool Declaration::isEventOrErrorParameter() const
615 {
616 	solAssert(scope(), "");
617 	return dynamic_cast<EventDefinition const*>(scope()) || dynamic_cast<ErrorDefinition const*>(scope());
618 }
619 
isVisibleAsUnqualifiedName() const620 bool Declaration::isVisibleAsUnqualifiedName() const
621 {
622 	if (!scope())
623 		return true;
624 	if (isStructMember() || isEnumValue() || isEventOrErrorParameter())
625 		return false;
626 	if (auto const* functionDefinition = dynamic_cast<FunctionDefinition const*>(scope()))
627 		if (!functionDefinition->isImplemented())
628 			return false; // parameter of a function without body
629 	return true;
630 }
631 
annotation() const632 DeclarationAnnotation& Declaration::annotation() const
633 {
634 	return initAnnotation<DeclarationAnnotation>();
635 }
636 
isLValue() const637 bool VariableDeclaration::isLValue() const
638 {
639 	// Constant declared variables are Read-Only
640 	return !isConstant();
641 }
642 
isLocalVariable() const643 bool VariableDeclaration::isLocalVariable() const
644 {
645 	auto s = scope();
646 	return
647 		dynamic_cast<FunctionTypeName const*>(s) ||
648 		dynamic_cast<CallableDeclaration const*>(s) ||
649 		dynamic_cast<Block const*>(s) ||
650 		dynamic_cast<TryCatchClause const*>(s) ||
651 		dynamic_cast<ForStatement const*>(s);
652 }
653 
isCallableOrCatchParameter() const654 bool VariableDeclaration::isCallableOrCatchParameter() const
655 {
656 	if (isReturnParameter() || isTryCatchParameter())
657 		return true;
658 
659 	vector<ASTPointer<VariableDeclaration>> const* parameters = nullptr;
660 
661 	if (auto const* funTypeName = dynamic_cast<FunctionTypeName const*>(scope()))
662 		parameters = &funTypeName->parameterTypes();
663 	else if (auto const* callable = dynamic_cast<CallableDeclaration const*>(scope()))
664 		parameters = &callable->parameters();
665 
666 	if (parameters)
667 		for (auto const& variable: *parameters)
668 			if (variable.get() == this)
669 				return true;
670 	return false;
671 }
672 
isLocalOrReturn() const673 bool VariableDeclaration::isLocalOrReturn() const
674 {
675 	return isReturnParameter() || (isLocalVariable() && !isCallableOrCatchParameter());
676 }
677 
isReturnParameter() const678 bool VariableDeclaration::isReturnParameter() const
679 {
680 	vector<ASTPointer<VariableDeclaration>> const* returnParameters = nullptr;
681 
682 	if (auto const* funTypeName = dynamic_cast<FunctionTypeName const*>(scope()))
683 		returnParameters = &funTypeName->returnParameterTypes();
684 	else if (auto const* callable = dynamic_cast<CallableDeclaration const*>(scope()))
685 		if (callable->returnParameterList())
686 			returnParameters = &callable->returnParameterList()->parameters();
687 
688 	if (returnParameters)
689 		for (auto const& variable: *returnParameters)
690 			if (variable.get() == this)
691 				return true;
692 	return false;
693 }
694 
isTryCatchParameter() const695 bool VariableDeclaration::isTryCatchParameter() const
696 {
697 	return dynamic_cast<TryCatchClause const*>(scope());
698 }
699 
isExternalCallableParameter() const700 bool VariableDeclaration::isExternalCallableParameter() const
701 {
702 	if (!isCallableOrCatchParameter())
703 		return false;
704 
705 	if (auto const* callable = dynamic_cast<CallableDeclaration const*>(scope()))
706 		if (callable->visibility() == Visibility::External)
707 			return !isReturnParameter();
708 
709 	return false;
710 }
711 
isPublicCallableParameter() const712 bool VariableDeclaration::isPublicCallableParameter() const
713 {
714 	if (!isCallableOrCatchParameter())
715 		return false;
716 
717 	if (auto const* callable = dynamic_cast<CallableDeclaration const*>(scope()))
718 		if (callable->visibility() == Visibility::Public)
719 			return !isReturnParameter();
720 
721 	return false;
722 }
723 
isInternalCallableParameter() const724 bool VariableDeclaration::isInternalCallableParameter() const
725 {
726 	if (!isCallableOrCatchParameter())
727 		return false;
728 
729 	if (auto const* funTypeName = dynamic_cast<FunctionTypeName const*>(scope()))
730 		return funTypeName->visibility() == Visibility::Internal;
731 	else if (auto const* callable = dynamic_cast<CallableDeclaration const*>(scope()))
732 		return callable->visibility() <= Visibility::Internal;
733 	return false;
734 }
735 
isConstructorParameter() const736 bool VariableDeclaration::isConstructorParameter() const
737 {
738 	if (!isCallableOrCatchParameter())
739 		return false;
740 	if (auto const* function = dynamic_cast<FunctionDefinition const*>(scope()))
741 		return function->isConstructor();
742 	return false;
743 }
744 
isLibraryFunctionParameter() const745 bool VariableDeclaration::isLibraryFunctionParameter() const
746 {
747 	if (!isCallableOrCatchParameter())
748 		return false;
749 	if (auto const* funDef = dynamic_cast<FunctionDefinition const*>(scope()))
750 		return funDef->libraryFunction();
751 	return false;
752 }
753 
hasReferenceOrMappingType() const754 bool VariableDeclaration::hasReferenceOrMappingType() const
755 {
756 	solAssert(typeName().annotation().type, "Can only be called after reference resolution");
757 	Type const* type = typeName().annotation().type;
758 	return type->category() == Type::Category::Mapping || dynamic_cast<ReferenceType const*>(type);
759 }
760 
isStateVariable() const761 bool VariableDeclaration::isStateVariable() const
762 {
763 	return dynamic_cast<ContractDefinition const*>(scope());
764 }
765 
isFileLevelVariable() const766 bool VariableDeclaration::isFileLevelVariable() const
767 {
768 	return dynamic_cast<SourceUnit const*>(scope());
769 }
770 
allowedDataLocations() const771 set<VariableDeclaration::Location> VariableDeclaration::allowedDataLocations() const
772 {
773 	using Location = VariableDeclaration::Location;
774 
775 	if (!hasReferenceOrMappingType() || isStateVariable() || isEventOrErrorParameter())
776 		return set<Location>{ Location::Unspecified };
777 	else if (isCallableOrCatchParameter())
778 	{
779 		set<Location> locations{ Location::Memory };
780 		if (
781 			isConstructorParameter() ||
782 			isInternalCallableParameter() ||
783 			isLibraryFunctionParameter()
784 		)
785 			locations.insert(Location::Storage);
786 		if (!isTryCatchParameter() && !isConstructorParameter())
787 			locations.insert(Location::CallData);
788 
789 		return locations;
790 	}
791 	else if (isLocalVariable())
792 		// Further restrictions will be imposed later on.
793 		return set<Location>{ Location::Memory, Location::Storage, Location::CallData };
794 	else
795 		// Struct members etc.
796 		return set<Location>{ Location::Unspecified };
797 }
798 
externalIdentifierHex() const799 string VariableDeclaration::externalIdentifierHex() const
800 {
801 	solAssert(isStateVariable() && isPublic(), "Can only be called for public state variables");
802 	return TypeProvider::function(*this)->externalIdentifierHex();
803 }
804 
type() const805 Type const* VariableDeclaration::type() const
806 {
807 	return annotation().type;
808 }
809 
functionType(bool _internal) const810 FunctionTypePointer VariableDeclaration::functionType(bool _internal) const
811 {
812 	if (_internal)
813 		return nullptr;
814 	switch (visibility())
815 	{
816 	case Visibility::Default:
817 		solAssert(false, "visibility() should not return Default");
818 	case Visibility::Private:
819 	case Visibility::Internal:
820 		return nullptr;
821 	case Visibility::Public:
822 	case Visibility::External:
823 		return TypeProvider::function(*this);
824 	}
825 
826 	// To make the compiler happy
827 	return nullptr;
828 }
829 
annotation() const830 VariableDeclarationAnnotation& VariableDeclaration::annotation() const
831 {
832 	return initAnnotation<VariableDeclarationAnnotation>();
833 }
834 
annotation() const835 StatementAnnotation& Statement::annotation() const
836 {
837 	return initAnnotation<StatementAnnotation>();
838 }
839 
annotation() const840 InlineAssemblyAnnotation& InlineAssembly::annotation() const
841 {
842 	return initAnnotation<InlineAssemblyAnnotation>();
843 }
844 
annotation() const845 BlockAnnotation& Block::annotation() const
846 {
847 	return initAnnotation<BlockAnnotation>();
848 }
849 
annotation() const850 TryCatchClauseAnnotation& TryCatchClause::annotation() const
851 {
852 	return initAnnotation<TryCatchClauseAnnotation>();
853 }
854 
annotation() const855 ForStatementAnnotation& ForStatement::annotation() const
856 {
857 	return initAnnotation<ForStatementAnnotation>();
858 }
859 
annotation() const860 ReturnAnnotation& Return::annotation() const
861 {
862 	return initAnnotation<ReturnAnnotation>();
863 }
864 
annotation() const865 ExpressionAnnotation& Expression::annotation() const
866 {
867 	return initAnnotation<ExpressionAnnotation>();
868 }
869 
annotation() const870 MemberAccessAnnotation& MemberAccess::annotation() const
871 {
872 	return initAnnotation<MemberAccessAnnotation>();
873 }
874 
annotation() const875 BinaryOperationAnnotation& BinaryOperation::annotation() const
876 {
877 	return initAnnotation<BinaryOperationAnnotation>();
878 }
879 
annotation() const880 FunctionCallAnnotation& FunctionCall::annotation() const
881 {
882 	return initAnnotation<FunctionCallAnnotation>();
883 }
884 
sortedArguments() const885 vector<ASTPointer<Expression const>> FunctionCall::sortedArguments() const
886 {
887 	// normal arguments
888 	if (m_names.empty())
889 		return arguments();
890 
891 	// named arguments
892 	FunctionTypePointer functionType;
893 	if (*annotation().kind == FunctionCallKind::StructConstructorCall)
894 	{
895 		auto const& type = dynamic_cast<TypeType const&>(*m_expression->annotation().type);
896 		auto const& structType = dynamic_cast<StructType const&>(*type.actualType());
897 		functionType = structType.constructorType();
898 	}
899 	else
900 		functionType = dynamic_cast<FunctionType const*>(m_expression->annotation().type);
901 
902 	vector<ASTPointer<Expression const>> sorted;
903 	for (auto const& parameterName: functionType->parameterNames())
904 	{
905 		bool found = false;
906 		for (size_t j = 0; j < m_names.size() && !found; j++)
907 			if ((found = (parameterName == *m_names.at(j))))
908 				// we found the actual parameter position
909 				sorted.push_back(m_arguments.at(j));
910 		solAssert(found, "");
911 	}
912 
913 	if (!functionType->takesArbitraryParameters())
914 	{
915 		solAssert(m_arguments.size() == functionType->parameterTypes().size(), "");
916 		solAssert(m_arguments.size() == m_names.size(), "");
917 		solAssert(m_arguments.size() == sorted.size(), "");
918 	}
919 
920 	return sorted;
921 }
922 
annotation() const923 IdentifierAnnotation& Identifier::annotation() const
924 {
925 	return initAnnotation<IdentifierAnnotation>();
926 }
927 
valueWithoutUnderscores() const928 ASTString Literal::valueWithoutUnderscores() const
929 {
930 	return boost::erase_all_copy(value(), "_");
931 }
932 
isHexNumber() const933 bool Literal::isHexNumber() const
934 {
935 	if (token() != Token::Number)
936 		return false;
937 	return boost::starts_with(value(), "0x");
938 }
939 
looksLikeAddress() const940 bool Literal::looksLikeAddress() const
941 {
942 	if (subDenomination() != SubDenomination::None)
943 		return false;
944 
945 	if (!isHexNumber())
946 		return false;
947 
948 	return abs(int(valueWithoutUnderscores().length()) - 42) <= 1;
949 }
950 
passesAddressChecksum() const951 bool Literal::passesAddressChecksum() const
952 {
953 	solAssert(isHexNumber(), "Expected hex number");
954 	return util::passesAddressChecksum(valueWithoutUnderscores(), true);
955 }
956 
getChecksummedAddress() const957 string Literal::getChecksummedAddress() const
958 {
959 	solAssert(isHexNumber(), "Expected hex number");
960 	/// Pad literal to be a proper hex address.
961 	string address = valueWithoutUnderscores().substr(2);
962 	if (address.length() > 40)
963 		return string();
964 	address.insert(address.begin(), 40 - address.size(), '0');
965 	return util::getChecksummedAddress(address);
966 }
967 
successClause() const968 TryCatchClause const* TryStatement::successClause() const
969 {
970 	solAssert(m_clauses.size() > 0, "");
971 	return m_clauses[0].get();
972 }
973 
panicClause() const974 TryCatchClause const* TryStatement::panicClause() const
975 {
976 	for (size_t i = 1; i < m_clauses.size(); ++i)
977 		if (m_clauses[i]->errorName() == "Panic")
978 			return m_clauses[i].get();
979 	return nullptr;
980 }
981 
errorClause() const982 TryCatchClause const* TryStatement::errorClause() const
983 {
984 	for (size_t i = 1; i < m_clauses.size(); ++i)
985 		if (m_clauses[i]->errorName() == "Error")
986 			return m_clauses[i].get();
987 	return nullptr;
988 }
989 
fallbackClause() const990 TryCatchClause const* TryStatement::fallbackClause() const
991 {
992 	for (size_t i = 1; i < m_clauses.size(); ++i)
993 		if (m_clauses[i]->errorName().empty())
994 			return m_clauses[i].get();
995 	return nullptr;
996 }
997