CXXToken * cxxTokenChainExtractRangeFilterTypeName( CXXToken * from, CXXToken * to ) { if(!from) return NULL; CXXToken * pToken = from; for(;;) { if(!cxxTokenTypeIs(pToken,CXXTokenTypeKeyword)) break; if(!cxxKeywordExcludeFromTypeNames(pToken->eKeyword)) break; // must be excluded if(pToken == to) return NULL; // only excluded keywords pToken = pToken->pNext; if(!pToken) return NULL; // ... bug? } // Got at least one non-excluded keyword CXXToken * pRet = cxxTokenCreate(); pRet->iLineNumber = pToken->iLineNumber; pRet->oFilePosition = pToken->oFilePosition; pRet->eType = pToken->eType; cxxTokenAppendToString(pRet->pszWord,pToken); if(pToken->bFollowedBySpace) vStringPut (pRet->pszWord, ' '); pRet->bFollowedBySpace = pToken->bFollowedBySpace; while(pToken != to) { pToken = pToken->pNext; if(!pToken) return pRet; // ... bug? for(;;) { if(!cxxTokenTypeIs(pToken,CXXTokenTypeKeyword)) break; if(!cxxKeywordExcludeFromTypeNames(pToken->eKeyword)) break; // must be excluded if(pToken == to) return pRet; pToken = pToken->pNext; if(!pToken) return pRet; // ... bug? } cxxTokenAppendToString(pRet->pszWord,pToken); if(pToken->bFollowedBySpace) vStringPut (pRet->pszWord, ' '); pRet->bFollowedBySpace = pToken->bFollowedBySpace; } return pRet; }
// In case of a lambda without parentheses this is the capture list token. boolean cxxParserHandleLambda(CXXToken * pParenthesis) { CXX_DEBUG_ENTER(); CXXToken * pIdentifier = cxxTokenCreateAnonymousIdentifier(CXXTagKindFUNCTION); CXXTokenChain * pSave = g_cxx.pTokenChain; CXXTokenChain * pNew = cxxTokenChainCreate(); g_cxx.pTokenChain = pNew; tagEntryInfo * tag = cxxTagBegin(CXXTagKindFUNCTION,pIdentifier); CXXToken * pAfterParenthesis = pParenthesis ? pParenthesis->pNext : NULL; CXXToken * pCaptureList = NULL; if(pParenthesis) { if(cxxTokenTypeIs(pParenthesis,CXXTokenTypeSquareParenthesisChain)) { // form (4) of lambda (see cxxParserOpeningBracketIsLambda()). pCaptureList = pParenthesis; } else if( pParenthesis->pPrev && cxxTokenTypeIs(pParenthesis->pPrev,CXXTokenTypeSquareParenthesisChain) ) { // other forms of lambda (see cxxParserOpeningBracketIsLambda()). pCaptureList = pParenthesis->pPrev; } } if( pAfterParenthesis && cxxTokenTypeIs(pAfterParenthesis,CXXTokenTypeKeyword) && (pAfterParenthesis->eKeyword == CXXKeywordCONST) ) pAfterParenthesis = pAfterParenthesis->pNext; CXXToken * pTypeStart = NULL; CXXToken * pTypeEnd; if( pAfterParenthesis && cxxTokenTypeIs(pAfterParenthesis,CXXTokenTypePointerOperator) && pAfterParenthesis->pNext && !cxxTokenTypeIs(pAfterParenthesis->pNext,CXXTokenTypeOpeningBracket) ) { pTypeStart = pAfterParenthesis->pNext; pTypeEnd = pTypeStart; while( pTypeEnd->pNext && (!cxxTokenTypeIs(pTypeEnd->pNext,CXXTokenTypeOpeningBracket)) ) pTypeEnd = pTypeEnd->pNext; while( (pTypeStart != pTypeEnd) && cxxTokenTypeIs(pTypeStart,CXXTokenTypeKeyword) && cxxKeywordExcludeFromTypeNames(pTypeStart->eKeyword) ) pTypeStart = pTypeStart->pNext; } int iCorkQueueIndex = CORK_NIL; if(tag) { tag->isFileScope = TRUE; CXXToken * pTypeName; if(pTypeStart) pTypeName = cxxTagSetTypeField(pTypeStart,pTypeEnd); else pTypeName = NULL; if(pCaptureList && cxxTagCPPFieldEnabled(CXXTagCPPFieldLambdaCaptureList)) { CXX_DEBUG_ASSERT(pCaptureList->pChain,"The capture list must be a chain"); cxxTokenChainCondense(pCaptureList->pChain,0); CXX_DEBUG_ASSERT( cxxTokenChainFirst(pCaptureList->pChain), "Condensation should have created a single token in the chain" ); cxxTagSetCPPField( CXXTagCPPFieldLambdaCaptureList, vStringValue(cxxTokenChainFirst(pCaptureList->pChain)->pszWord) ); } // FIXME: Properties? vString * pszSignature = NULL; if(cxxTokenTypeIs(pParenthesis,CXXTokenTypeParenthesisChain)) pszSignature = cxxTokenChainJoin(pParenthesis->pChain,NULL,0); if(pszSignature) tag->extensionFields.signature = vStringValue(pszSignature); iCorkQueueIndex = cxxTagCommit(); if(pTypeName) cxxTokenDestroy(pTypeName); if(pszSignature) vStringDelete(pszSignature); } cxxScopePush( pIdentifier, CXXTagKindFUNCTION, CXXScopeAccessUnknown ); if( pParenthesis && cxxTokenTypeIs(pParenthesis,CXXTokenTypeParenthesisChain) && cxxTagKindEnabled(CXXTagKindPARAMETER) ) { CXXFunctionParameterInfo oParamInfo; if(cxxParserTokenChainLooksLikeFunctionParameterList( pParenthesis->pChain,&oParamInfo )) cxxParserEmitFunctionParameterTags(&oParamInfo); } boolean bRet = cxxParserParseBlock(TRUE); if(iCorkQueueIndex > CORK_NIL) cxxParserMarkEndLineForTagInCorkQueue(iCorkQueueIndex); cxxScopePop(); pNew = g_cxx.pTokenChain; // May have been destroyed and re-created g_cxx.pTokenChain = pSave; g_cxx.pToken = pSave->pTail; // change the type of token so following parsing code is not confused too much g_cxx.pToken->eType = CXXTokenTypeAngleBracketChain; g_cxx.pToken->pChain = pNew; cxxTokenChainClear(pNew); CXXToken * t = cxxTokenCreate(); t->eType = CXXTokenTypeOpeningBracket; vStringCatS(t->pszWord,"{"); cxxTokenChainAppend(pNew,t); t = cxxTokenCreate(); t->eType = CXXTokenTypeClosingBracket; vStringCatS(t->pszWord,"}"); cxxTokenChainAppend(pNew,t); CXX_DEBUG_LEAVE(); return bRet; }