14df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni/* 24df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni * Copyright 2017, The Android Open Source Project 34df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni * 44df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni * Licensed under the Apache License, Version 2.0 (the "License"); 54df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni * you may not use this file except in compliance with the License. 64df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni * You may obtain a copy of the License at 74df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni * 84df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni * http://www.apache.org/licenses/LICENSE-2.0 94df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni * 104df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni * Unless required by applicable law or agreed to in writing, software 114df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni * distributed under the License is distributed on an "AS IS" BASIS, 124df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 134df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni * See the License for the specific language governing permissions and 144df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni * limitations under the License. 154df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni */ 164df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni 173f30b6202dd5ad6ff66959131d216405850ed152Yang Ni#include "module.h" 184df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni 194df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni#include "file_utils.h" 204df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni#include "instructions.h" 214df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni#include "test_utils.h" 224df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni#include "gtest/gtest.h" 234df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni 243f30b6202dd5ad6ff66959131d216405850ed152Yang Ni#include <fstream> 253f30b6202dd5ad6ff66959131d216405850ed152Yang Ni#include <memory> 263f30b6202dd5ad6ff66959131d216405850ed152Yang Ni 274df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ninamespace android { 284df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ninamespace spirit { 294df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni 304df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Niclass ModuleTest : public ::testing::Test { 314df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Niprotected: 324df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni virtual void SetUp() { 3328faded3432d20cc2e9b9e58b4706031bd6ea9c9Yang Ni mWordsGlobal = readWords("global.spv"); 344df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni mWordsGreyscale = readWords("greyscale.spv"); 354df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni mWordsGreyscale2 = readWords("greyscale2.spv"); 364df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni mWordsInvert = readWords("invert.spv"); 374df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni } 384df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni 3928faded3432d20cc2e9b9e58b4706031bd6ea9c9Yang Ni std::vector<uint32_t> mWordsGlobal; 404df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni std::vector<uint32_t> mWordsGreyscale; 414df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni std::vector<uint32_t> mWordsGreyscale2; 424df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni std::vector<uint32_t> mWordsInvert; 434df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni 444df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Niprivate: 454df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni std::vector<uint32_t> readWords(const char *testFile) { 464df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni static const std::string testDataPath( 474df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni "frameworks/rs/rsov/compiler/spirit/test_data/"); 484df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni const std::string &fullPath = getAbsolutePath(testDataPath + testFile); 494df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni return readFile<uint32_t>(fullPath); 504df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni } 514df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni}; 524df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni 534df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang NiTEST_F(ModuleTest, testDeserialization1) { 543e5fbb6faf66488ba49c9d2396350ae567dba315Yang Ni auto m = Deserialize<Module>(mWordsGreyscale); 554df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni 564df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni ASSERT_NE(nullptr, m); 574df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni 584df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni std::unique_ptr<Module> mDeleter(m); 594df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni 604df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni int count = 0; 614df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni std::unique_ptr<IVisitor> v( 624df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni CreateInstructionVisitor([&count](Instruction *) -> void { count++; })); 634df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni v->visit(m); 644df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni 654df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni ASSERT_EQ(count, 123); 664df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni 674df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni // TODO:: checkCountEntity<Instruction>() does not work correctly 684df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni // EXPECT_TRUE(checkCountEntity<Instruction>(m, 123)); 694df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni EXPECT_EQ(5, countEntity<AccessChainInst>(m)); 704df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni EXPECT_EQ(2, countEntity<BitcastInst>(m)); 714df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni EXPECT_EQ(1, countEntity<CapabilityInst>(m)); 724df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni EXPECT_EQ(1, countEntity<CompositeConstructInst>(m)); 734df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni EXPECT_EQ(5, countEntity<ConstantInst>(m)); 744df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni EXPECT_EQ(1, countEntity<ConstantCompositeInst>(m)); 754df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni EXPECT_EQ(11, countEntity<DecorateInst>(m)); 764df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni EXPECT_EQ(1, countEntity<DotInst>(m)); 774df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni EXPECT_EQ(1, countEntity<EntryPointInst>(m)); 784df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni EXPECT_EQ(1, countEntity<ExecutionModeInst>(m)); 794df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni EXPECT_EQ(1, countEntity<ExtInstImportInst>(m)); 804df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni EXPECT_EQ(2, countEntity<FunctionInst>(m)); 814df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni EXPECT_EQ(1, countEntity<FunctionCallInst>(m)); 824df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni EXPECT_EQ(2, countEntity<FunctionEndInst>(m)); 834df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni EXPECT_EQ(1, countEntity<FunctionParameterInst>(m)); 844df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni EXPECT_EQ(1, countEntity<IAddInst>(m)); 854df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni EXPECT_EQ(1, countEntity<IMulInst>(m)); 864df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni EXPECT_EQ(1, countEntity<ImageInst>(m)); 874df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni EXPECT_EQ(1, countEntity<ImageFetchInst>(m)); 884df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni EXPECT_EQ(2, countEntity<LabelInst>(m)); 894df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni EXPECT_EQ(11, countEntity<LoadInst>(m)); 904df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni EXPECT_EQ(4, countEntity<MemberDecorateInst>(m)); 914df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni EXPECT_EQ(4, countEntity<MemberNameInst>(m)); 924df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni EXPECT_EQ(1, countEntity<MemoryModelInst>(m)); 934df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni EXPECT_EQ(14, countEntity<NameInst>(m)); 944df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni EXPECT_EQ(1, countEntity<ReturnInst>(m)); 954df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni EXPECT_EQ(1, countEntity<ReturnValueInst>(m)); 964df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni EXPECT_EQ(1, countEntity<SourceInst>(m)); 974df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni EXPECT_EQ(3, countEntity<SourceExtensionInst>(m)); 984df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni EXPECT_EQ(6, countEntity<StoreInst>(m)); 994df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni EXPECT_EQ(1, countEntity<TypeFloatInst>(m)); 1004df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni EXPECT_EQ(2, countEntity<TypeFunctionInst>(m)); 1014df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni EXPECT_EQ(1, countEntity<TypeImageInst>(m)); 1024df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni EXPECT_EQ(2, countEntity<TypeIntInst>(m)); 1034df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni EXPECT_EQ(10, countEntity<TypePointerInst>(m)); 1044df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni EXPECT_EQ(1, countEntity<TypeRuntimeArrayInst>(m)); 1054df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni EXPECT_EQ(1, countEntity<TypeSampledImageInst>(m)); 1064df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni EXPECT_EQ(2, countEntity<TypeStructInst>(m)); 1074df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni EXPECT_EQ(4, countEntity<TypeVectorInst>(m)); 1084df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni EXPECT_EQ(1, countEntity<TypeVoidInst>(m)); 1094df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni EXPECT_EQ(9, countEntity<VariableInst>(m)); 1104df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni EXPECT_EQ(1, countEntity<VectorShuffleInst>(m)); 1114df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni EXPECT_EQ(1, countEntity<EntryPointDefinition>(m)); 1124df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni EXPECT_EQ(1, countEntity<DebugInfoSection>(m)); 1134df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni EXPECT_EQ(1, countEntity<GlobalSection>(m)); 1144df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni EXPECT_EQ(2, countEntity<FunctionDefinition>(m)); 1154df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni} 1164df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni 1174df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang NiTEST_F(ModuleTest, testDeserialization2) { 1183e5fbb6faf66488ba49c9d2396350ae567dba315Yang Ni Module *m = Deserialize<Module>(mWordsInvert); 1194df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni ASSERT_NE(nullptr, m); 1204df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni 1214df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni std::unique_ptr<Module> mDeleter(m); 1224df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni 1233e5fbb6faf66488ba49c9d2396350ae567dba315Yang Ni auto outwords = Serialize<Module>(m); 1244df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni 1254df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni EXPECT_TRUE(mWordsInvert == outwords); 1264df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni} 1274df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni 1284df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang NiTEST_F(ModuleTest, testSerialization1) { 1293e5fbb6faf66488ba49c9d2396350ae567dba315Yang Ni Module *m = Deserialize<Module>(mWordsGreyscale); 1304df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni ASSERT_NE(nullptr, m); 1314df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni 1324df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni std::unique_ptr<Module> mDeleter(m); 1334df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni 1344df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni EXPECT_EQ(2, countEntity<FunctionDefinition>(m)); 1354df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni 1363e5fbb6faf66488ba49c9d2396350ae567dba315Yang Ni auto outwords = Serialize<Module>(m); 1374df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni 1384df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni EXPECT_TRUE(mWordsGreyscale == outwords); 1394df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni} 1404df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni 1414df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang NiTEST_F(ModuleTest, testSerialization2) { 1423e5fbb6faf66488ba49c9d2396350ae567dba315Yang Ni Module *m = Deserialize<Module>(mWordsGreyscale2); 1434df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni ASSERT_NE(nullptr, m); 1444df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni 1454df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni std::unique_ptr<Module> mDeleter(m); 1464df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni 1474df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni EXPECT_EQ(1, countEntity<FunctionDefinition>(m)); 1484df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni 1493e5fbb6faf66488ba49c9d2396350ae567dba315Yang Ni auto outwords = Serialize<Module>(m); 1504df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni 1514df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni EXPECT_TRUE(mWordsGreyscale2 == outwords); 1524df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni} 1534df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni 1544df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang NiTEST_F(ModuleTest, testLookupByName) { 1553e5fbb6faf66488ba49c9d2396350ae567dba315Yang Ni Module *m = Deserialize<Module>(mWordsGreyscale); 1564df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni 1574df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni ASSERT_NE(nullptr, m); 1584df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni 1594df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni std::unique_ptr<Module> mDeleter(m); 1604df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni 1614df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni m->resolveIds(); 1624df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni 1634df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni Instruction *mainFunc = m->lookupByName("main"); 1644df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni 1654df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni EXPECT_NE(nullptr, mainFunc); 1664df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni EXPECT_STREQ("main", m->lookupNameByInstruction(mainFunc)); 1674df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni 1684df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni auto i = static_cast<FunctionInst *>(m->lookupByName("greyscale(vf4;")); 1694df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni ASSERT_NE(nullptr, i); 1704df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni 1714df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni auto kernel = m->getFunctionDefinitionFromInstruction(i); 1724df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni ASSERT_NE(nullptr, kernel); 1734df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni 1744df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni auto pt = static_cast<FunctionInst *>(m->lookupByName("greyscale(vf4;")); 1754df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni EXPECT_NE(nullptr, kernel->getParameter(0)); 1764df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni EXPECT_NE(nullptr, kernel->getReturnType()); 1774df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni 1784df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni EXPECT_NE(nullptr, m->lookupFunctionDefinitionByName("greyscale(vf4;")); 1794df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni} 1804df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni 1814df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang NiTEST_F(ModuleTest, testGetSize) { 1824df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni std::unique_ptr<Module> m(new Module()); 1834df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni EXPECT_EQ(4UL, m->getSize(m->getIntType(32))); 1844df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni EXPECT_EQ(4UL, m->getSize(m->getIntType(32, 0))); 1854df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni EXPECT_EQ(4UL, m->getSize(m->getFloatType(32))); 1864df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni EXPECT_EQ(16UL, m->getSize(m->getVectorType(m->getFloatType(32), 4))); 1874df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni} 1884df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni 18928faded3432d20cc2e9b9e58b4706031bd6ea9c9Yang NiTEST_F(ModuleTest, testFindStringOfPrefix) { 19028faded3432d20cc2e9b9e58b4706031bd6ea9c9Yang Ni Module *m = Deserialize<Module>(mWordsGlobal); 19128faded3432d20cc2e9b9e58b4706031bd6ea9c9Yang Ni 19228faded3432d20cc2e9b9e58b4706031bd6ea9c9Yang Ni ASSERT_NE(nullptr, m); 19328faded3432d20cc2e9b9e58b4706031bd6ea9c9Yang Ni 19428faded3432d20cc2e9b9e58b4706031bd6ea9c9Yang Ni std::unique_ptr<Module> mDeleter(m); 19528faded3432d20cc2e9b9e58b4706031bd6ea9c9Yang Ni ASSERT_STREQ(".rsov.ExportedVars:0;", 19628faded3432d20cc2e9b9e58b4706031bd6ea9c9Yang Ni m->findStringOfPrefix(".rsov.ExportedVars:").c_str()); 19728faded3432d20cc2e9b9e58b4706031bd6ea9c9Yang Ni 19828faded3432d20cc2e9b9e58b4706031bd6ea9c9Yang Ni} 19928faded3432d20cc2e9b9e58b4706031bd6ea9c9Yang Ni 2004df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni} // namespace spirit 2014df77d18bf57187f8e7142c6f7a70a9cdd3d581eYang Ni} // namespace android 202