| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You under the Apache License, Version 2.0 |
| * (the "License"); you may not use this file except in compliance with |
| * the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| #include "../../base_types.hpp" |
| #include <stdio.h> |
| #ifndef WIN32 |
| #include <strings.h> |
| #endif |
| #include "CPPInputParser.hpp" |
| #include "../../impl/Log.hpp" |
| #include <fstream> |
| #include <antlr/ANTLRException.hpp> |
| |
| // Used to control selected tracing at statement level. |
| extern int statementTrace; |
| |
| int deferredLineCount = 0; |
| |
| void process_line_directive(const char* includedFile, |
| const char* includedLineNo) {} |
| |
| ANTLR_USING_NAMESPACE(antlr); |
| |
| namespace apache { |
| namespace geode { |
| namespace client { |
| namespace pdx_auto_serializer { |
| /** The name of this module to be used for logging. */ |
| static std::string ModuleName = "CPPInputParser"; |
| |
| // CPPClassInfo definitions |
| |
| std::string CPPClassInfo::getName() const { return m_className; } |
| |
| std::string CPPClassInfo::getMethodPrefix() const { return m_method_prefix; } |
| |
| void CPPClassInfo::getReferences(ReferenceVector& references) const { |
| if (m_headerName.length() > 0) { |
| ReferenceInfo classHeader = {m_headerName, Reference::HEADER}; |
| |
| references.push_back(classHeader); |
| } |
| |
| /*ReferenceInfo builtinHeader = { "ASBuiltins.hpp", |
| Reference::HEADER };*/ |
| |
| // references.push_back(builtinHeader); |
| |
| /*ReferenceInfo builtinHeaderWriter = { "geode/PdxWriter.hpp", |
| Reference::HEADER }; |
| references.push_back(builtinHeaderWriter); |
| |
| ReferenceInfo builtinHeaderReader = { "geode/PdxWriter.hpp", |
| Reference::HEADER }; |
| references.push_back(builtinHeaderReader);*/ |
| } |
| |
| void CPPClassInfo::getTypeInfo(TypeInfo& classInfo) const { |
| classInfo.m_kind = TypeKind::VALUE; |
| classInfo.m_nameOrSize = m_className; |
| classInfo.m_nameOfArrayElemSize = m_className; |
| classInfo.m_children = NULL; |
| classInfo.m_numChildren = 0; |
| classInfo.m_namespaces = m_NamespacesList; |
| } |
| |
| void CPPClassInfo::getMembers(VariableVector& members) const { |
| for (VariableVectorIterator memberIterator = m_members.begin(); |
| memberIterator != m_members.end(); ++memberIterator) { |
| members.push_back(*memberIterator); |
| } |
| } |
| |
| void CPPClassInfo::setHeaderName(const std::string headerName) { |
| m_headerName = headerName; |
| } |
| |
| void CPPClassInfo::setClassName(const std::string className) { |
| m_className = className; |
| } |
| |
| void CPPClassInfo::setMethodPrefix(const std::string className) { |
| m_method_prefix = m_method_prefix + className + "::"; |
| } |
| |
| void CPPClassInfo::addMember(const VariableInfo& member) { |
| m_members.push_back(member); |
| } |
| |
| void CPPClassInfo::addNamespace(std::vector<std::string>& inNamespaceVector) { |
| for (std::vector<std::string>::iterator itr = inNamespaceVector.begin(); |
| itr != inNamespaceVector.end(); ++itr) { |
| m_NamespacesList.push_back(*itr); |
| } |
| } |
| |
| CPPClassInfo::CPPClassInfo() { m_method_prefix = ""; } |
| |
| CPPClassInfo::~CPPClassInfo() {} |
| |
| // CPPHeaderParser definitions |
| |
| void CPPHeaderParser::beginClassDefinition(TypeSpecifier ts, const char* tag) { |
| CPPParser::beginClassDefinition(ts, tag); |
| m_currentClassesVector.push_back(new CPPClassInfo()); |
| m_currentClassesVector.back()->setHeaderName(getFilename()); |
| m_currentClassesVector.back()->setClassName(tag); |
| |
| if (m_currentClassesVector.size() > 1) { |
| for (std::vector<CPPClassInfo*>::iterator iter = |
| m_currentClassesVector.begin(); |
| iter != m_currentClassesVector.end() - 1; ++iter) { |
| m_currentClassesVector.back()->setMethodPrefix((*iter)->getName()); |
| } |
| } |
| m_currentClassScope = symbols->getCurrentScopeIndex(); |
| } |
| |
| void CPPHeaderParser::exitNamespaceScope() { m_namespaceVector.pop_back(); } |
| |
| void CPPHeaderParser::endClassDefinition() { |
| CPPParser::endClassDefinition(); |
| if (m_currentClassesVector.size() == 0) return; |
| if (m_arraySizeRefMap.size() > 0) { |
| for (VariableVector::iterator memberIterator = |
| m_currentClassesVector.back()->m_members.begin(); |
| memberIterator != m_currentClassesVector.back()->m_members.end(); |
| memberIterator++) { |
| StringMap::const_iterator findMember = |
| m_arraySizeRefMap.find(memberIterator->m_name); |
| if (findMember != m_arraySizeRefMap.end()) { |
| memberIterator->m_type.m_kind |= TypeKind::ARRAY; |
| memberIterator->m_type.m_nameOrSize = findMember->second; |
| Log::info(ModuleName, |
| "Using \"" + findMember->second + "\" as size of array \"" + |
| memberIterator->m_name + '"'); |
| } |
| |
| StringMap::const_iterator findMemberElem = |
| m_arrayElemSizeRefMap.find(memberIterator->m_name); |
| if (findMemberElem != m_arrayElemSizeRefMap.end()) { |
| memberIterator->m_type.m_kind |= TypeKind::ARRAY; |
| memberIterator->m_type.m_nameOfArrayElemSize = findMemberElem->second; |
| Log::info(ModuleName, |
| "Using \"" + findMemberElem->second + |
| "\" as size of array \"" + memberIterator->m_name + '"'); |
| } |
| } |
| } |
| /* |
| * add the namespace informaton here |
| */ |
| m_currentClassesVector.back()->addNamespace(m_namespaceVector); |
| |
| m_classes[m_currentClassesVector.back()->getName()] = std::make_pair( |
| static_cast<ClassInfo*>(m_currentClassesVector.back()), m_selectAll); |
| m_currentClassesVector.pop_back(); |
| m_currentClassScope = -1; |
| } |
| |
| void CPPHeaderParser::declaratorID(const char* id, QualifiedItem item) { |
| CPPParser::declaratorID(id, item); |
| if (item == qiNamespace) { |
| m_namespaceVector.push_back(id); |
| } |
| if (m_currentClassesVector.size() != 0 && m_currentClassScope >= 0 && |
| m_currentClassScope == symbols->getCurrentScopeIndex()) { |
| if (item == qiVar) { // check if this is a member field declaration |
| if (m_currentInclude && m_currentArraySizeRef.length() == 0 && |
| m_currentArrayElemSizeRef.length() == 0) { |
| VariableInfo var; |
| |
| var.m_type.m_kind = TypeKind::VALUE; |
| var.m_type.m_modifier = TypeModifier::NONE; |
| var.m_type.m_children = NULL; |
| var.m_type.m_numChildren = 0; |
| var.m_name = id; |
| if (m_markIdentityField == true) { |
| var.m_markIdentityField = true; |
| } else { |
| var.m_markIdentityField = false; |
| } |
| |
| if (m_markPdxUnreadField == true) { |
| var.m_markPdxUnreadField = true; |
| } else { |
| var.m_markPdxUnreadField = false; |
| } |
| |
| m_currentClassesVector.back()->addMember(var); |
| } |
| /*else if ( item == qiType ) { |
| m_currentClass->addNamespace(id); |
| }*/ |
| else if (m_currentArraySizeRef.length() > 0) { |
| if (NULL == strchr(m_currentArraySizeRef.c_str(), ',')) { |
| m_arraySizeRefMap[m_currentArraySizeRef] = id; |
| } else { |
| m_currentArraySizeRef.erase(m_currentArraySizeRef.begin()); |
| m_currentArraySizeRef.erase(m_currentArraySizeRef.end() - 1); |
| char* p = |
| strtok(const_cast<char*>(m_currentArraySizeRef.c_str()), ","); |
| while (p) { |
| m_arraySizeRefMap[p] = id; |
| p = strtok(NULL, ","); |
| } |
| } |
| } else if (m_currentArrayElemSizeRef.length() > 0) { |
| // std::cout << "Map Entries --> " << "m_arrayElemSizeRefMap[" << |
| // m_currentArrayElemSizeRef <<"] = " << id << std::endl; |
| m_arrayElemSizeRefMap[m_currentArrayElemSizeRef] = id; |
| } |
| } |
| } |
| // m_currentInclude = true; |
| m_currentArraySizeRef = ""; |
| m_currentArrayElemSizeRef = ""; |
| } |
| |
| void CPPHeaderParser::declarationSpecifier(bool td, bool fd, StorageClass sc, |
| TypeQualifier tq, TypeSpecifier ts, |
| FunctionSpecifier fs) { |
| CPPParser::declarationSpecifier(td, fd, sc, tq, ts, fs); |
| if ((tq & tqCONST) || ((tq & tqGFEXCLUDE) && !(tq & tqGFINCLUDE))) { |
| m_currentInclude = false; |
| } else { |
| m_currentInclude = true; |
| } |
| if (tq & tqGFID) { |
| m_markIdentityField = true; |
| } else { |
| m_markIdentityField = false; |
| } |
| if (tq & tqGFUNREAD) { |
| m_markPdxUnreadField = true; |
| } else { |
| m_markPdxUnreadField = false; |
| } |
| } |
| |
| void CPPHeaderParser::gfArraySize(const char* id) { |
| m_currentArraySizeRef = id; |
| } |
| |
| void CPPHeaderParser::gfArrayElemSize(const char* id) { |
| m_currentArrayElemSizeRef = id; |
| } |
| |
| CPPHeaderParser::CPPHeaderParser(CPPLexer& lexer, ASClassFlagMap& classes, |
| const bool selectAll) |
| : CPPParser(lexer), |
| m_classes(classes), |
| m_selectAll(selectAll), |
| m_currentClassesVector(std::vector<CPPClassInfo*>()), |
| m_currentClassScope(-1), |
| m_currentInclude(true), |
| m_markIdentityField(false), |
| m_markPdxUnreadField(false) {} |
| |
| // CPPInputParser definitions |
| |
| void CPPInputParser::getOptions(OptionMap& options) const {} |
| |
| void CPPInputParser::init(PropertyMap& properties) {} |
| |
| void CPPInputParser::selectClasses(const StringVector& resources, |
| const StringVector& classNames) { |
| #ifndef _DEBUG |
| statementTrace = 0; |
| #endif |
| statementTrace = 0; |
| bool selectAll = (classNames.size() == 0); |
| for (StringVectorIterator resourceIterator = resources.begin(); |
| resourceIterator != resources.end(); ++resourceIterator) { |
| try { |
| std::ifstream istream(resourceIterator->c_str()); |
| CPPLexer lexer(istream); |
| CPPHeaderParser parser(lexer, m_classes, selectAll); |
| parser.init(); |
| parser.setFilename(*resourceIterator); |
| parser.translation_unit(); |
| } catch (const ANTLRException& ex) { |
| throw std::invalid_argument(ex.getMessage()); |
| } |
| } |
| |
| for (StringVectorIterator classIterator = classNames.begin(); |
| classIterator != classNames.end(); ++classIterator) { |
| if (!select(*classIterator)) { |
| std::string warnMsg = |
| "Could not load class '" + *classIterator + "'; skipping it."; |
| Log::warn(ModuleName, warnMsg); |
| } |
| } |
| } |
| |
| CPPInputParser::CPPInputParser() {} |
| |
| InputParser* CPPInputParser::create() { return new CPPInputParser(); } |
| |
| CPPInputParser::~CPPInputParser() {} |
| } // namespace pdx_auto_serializer |
| } // namespace client |
| } // namespace geode |
| } // namespace apache |