static rescanReason cxxParserMain(const unsigned int passCount) { cxxScopeClear(); cxxTokenAPINewFile(); cxxParserNewStatement(); kindOption * kind_for_define = cxxTagGetKindOptions() + CXXTagKindMACRO; kindOption * kind_for_header = cxxTagGetKindOptions() + CXXTagKindINCLUDE; int role_for_macro_undef = CR_MACRO_UNDEF; int role_for_header_system = CR_HEADER_SYSTEM; int role_for_header_local = CR_HEADER_LOCAL; int end_field_type = cxxParserCurrentLanguageIsCPP()? cxxTagGetCPPFieldSpecifiers () [CXXTagCPPFieldEndLine].ftype: cxxTagGetCFieldSpecifiers () [CXXTagCFieldEndLine].ftype; Assert(passCount < 3); cppInit( (boolean) (passCount > 1), FALSE, TRUE, // raw literals FALSE, kind_for_define, role_for_macro_undef, kind_for_header, role_for_header_system, role_for_header_local, end_field_type ); g_cxx.iChar = ' '; boolean bRet = cxxParserParseBlock(FALSE); cppTerminate (); cxxTokenChainClear(g_cxx.pTokenChain); if(g_cxx.pTemplateTokenChain) cxxTokenChainClear(g_cxx.pTemplateTokenChain); if(!bRet && (passCount == 1)) { CXX_DEBUG_PRINT("Processing failed: trying to rescan"); return RESCAN_FAILED; } return RESCAN_NONE; }
parserDefinition * CppParser (void) { static const char * const extensions [] = { "c++", "cc", "cp", "cpp", "cxx", "h", "h++", "hh", "hp", "hpp", "hxx", "inl", #ifndef CASE_INSENSITIVE_FILENAMES "C", "H", "CPP", "CXX", #endif NULL }; static selectLanguage selectors[] = { selectByObjectiveCKeywords, NULL }; parserDefinition* def = parserNew("C++"); def->kinds = cxxTagGetKindOptions(); def->kindCount = cxxTagGetKindOptionCount(); def->extensions = extensions; def->parser2 = cxxCppParserMain; def->initialize = cxxCppParserInitialize; def->selectLanguage = selectors; def->useCork = TRUE; // We use corking to block output until the end of file return def; }
// // This is called after a full enum/struct/class/union declaration // that ends with a closing bracket. // static boolean cxxParserParseEnumStructClassOrUnionFullDeclarationTrailer( boolean bParsingTypedef, enum CXXKeyword eTagKeyword, enum CXXTagKind eTagKind, const char * szTypeName ) { CXX_DEBUG_ENTER(); cxxTokenChainClear(g_cxx.pTokenChain); CXX_DEBUG_PRINT( "Parse enum/struct/class/union trailer, typename is '%s'", szTypeName ); MIOPos oFilePosition = getInputFilePosition(); int iFileLine = getInputLineNumber(); if(!cxxParserParseUpToOneOf(CXXTokenTypeEOF | CXXTokenTypeSemicolon)) { CXX_DEBUG_LEAVE_TEXT("Failed to parse up to EOF/semicolon"); return FALSE; } if(cxxTokenTypeIs(g_cxx.pToken,CXXTokenTypeEOF)) { // It's a syntax error, but we can be tolerant here. CXX_DEBUG_LEAVE_TEXT("Got EOF after enum/class/struct/union block"); return TRUE; } if(g_cxx.pTokenChain->iCount < 2) { CXX_DEBUG_LEAVE_TEXT("Nothing interesting after enum/class/struct block"); return TRUE; } // fake the initial two tokens CXXToken * pIdentifier = cxxTokenCreate(); pIdentifier->oFilePosition = oFilePosition; pIdentifier->iLineNumber = iFileLine; pIdentifier->eType = CXXTokenTypeIdentifier; pIdentifier->bFollowedBySpace = TRUE; vStringCatS(pIdentifier->pszWord,szTypeName); cxxTokenChainPrepend(g_cxx.pTokenChain,pIdentifier); CXXToken * pKeyword = cxxTokenCreate(); pKeyword->oFilePosition = oFilePosition; pKeyword->iLineNumber = iFileLine; pKeyword->eType = CXXTokenTypeKeyword; pKeyword->eKeyword = eTagKeyword; pKeyword->bFollowedBySpace = TRUE; vStringCatS(pKeyword->pszWord,cxxTagGetKindOptions()[eTagKind].name); cxxTokenChainPrepend(g_cxx.pTokenChain,pKeyword); if(bParsingTypedef) cxxParserExtractTypedef(g_cxx.pTokenChain,TRUE); else cxxParserExtractVariableDeclarations(g_cxx.pTokenChain,0); CXX_DEBUG_LEAVE(); return TRUE; }