blob: be756df98e732611d42113b8809e09b3783ae687 [file] [log] [blame]
/*
* 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