// Return true if ID<...> or ID is last item in qualified item list. // Return false if LT(k) is not an ID. // ID must be a type to check for ID<...>, // or else we would get confused by "i<3" int CPPParser:: finalQualifier(int k) { if (LT(k)->getType()==ID) { if (isTypeName((LT(k)->getText()).data()) && LT(k+1)->getType()==LESSTHAN) {// Starts with "T<". Skip <...> k++; skipTemplateQualifiers(k); } else {// skip ID; k++; } return (LT(k)->getType() != SCOPE ); } else {// not an ID return 0; } }
bool QNEPort::isIO() { return !( isDisplayName() || isTypeName() ); }
CPPParser::QualifiedItem CPPParser::qualifiedItemIs(int lookahead_offset) { int k = lookahead_offset + 1; int final_type_idx = 0; bool scope_found = false; // Skip leading "::" if (LT(k)->getType() == SCOPE) {k++; scope_found = true;} // Skip sequences of T:: or T<...>:: //printf("support.cpp qualifiedItemIs while reached k %d type %d isType %d, isClass %d, guessing %d\n", // k,LT(k)->getType(),isTypeName((LT(k)->getText()).data()),isClassName((LT(k)->getText()).data()),inputState->guessing); while (LT(k)->getType() == ID && isTypeName((LT(k)->getText()).data())) {// If this type is the same as the last type, then ctor if (final_type_idx != 0 && strcmp((LT(final_type_idx)->getText()).data(), (LT(k)->getText()).data()) == 0) {// Like T::T // As an extra check, do not allow T::T:: if (LT(k+1)->getType() == SCOPE) {//printf("support.cpp qualifiedItemIs qiInvalid returned\n"); return qiInvalid; } else {//printf("support.cpp qualifiedItemIs qiCtor returned\n"); return qiCtor; } } // Record this as the most recent type seen in the series final_type_idx = k; //printf("support.cpp qualifiedItemIs if step reached final_type_idx %d\n",final_type_idx); // Skip this token k++; // Skip over any template qualifiers <...> // I believe that "T<..." cannot be anything valid but a template if (LT(k)->getType() == LESSTHAN) { if (!skipTemplateQualifiers(k)) {//printf("support.cpp qualifiedItemIs qiInvalid(2) returned\n"); return qiInvalid;} //printf("support.cpp qualifiedItemIs template skipped, k %d\n",k); // k has been updated to token following <...> } if (LT(k)->getType() == SCOPE) // Skip the "::" and keep going {k++; scope_found = true;} else {// Series terminated -- last ID in the sequence was a type // Return ctor if last type is in containing class // We already checked for T::T inside loop if ( strcmp(enclosingClass, (LT(final_type_idx)->getText()).data())==0 ) {// Like class T T() //printf("support.cpp qualifiedItemIs qiCtor(2) returned\n"); return qiCtor; } else {//printf("support.cpp qualifiedItemIs qiType returned\n"); return qiType;} } } // LT(k) is not an ID, or it is an ID but not a typename. //printf("support.cpp qualifiedItemIs second switch reached\n"); switch (LT(k)->getType()) { case ID: // ID but not a typename // Do not allow id:: if (LT(k+1)->getType() == SCOPE) { //printf("support.cpp qualifiedItemIs qiInvalid(3) returned\n"); return qiInvalid;} if (strcmp(enclosingClass,(LT(k)->getText()).data())==0 ) {// Like class T T() //printf("support.cpp qualifiedItemIs qiCtor(3) returned\n"); return qiCtor; } else { if (scope_found) // DW 25/10/03 Assume type if at least one SCOPE present (test12.i) return qiType; else //printf("support.cpp qualifiedItemIs qiVar returned\n"); return qiVar; // DW 19/03/04 was qiID Could be function? } case TILDE: // check for dtor if (LT(k+1)->getType() == ID && isTypeName((LT(k+1)->getText()).data()) && LT(k+2)->getType() != SCOPE) {// Like ~B or A::B::~B // Also (incorrectly?) matches ::~A. //printf("support.cpp qualifiedItemIs qiDtor returned\n"); return qiDtor; } else {// ~a or ~A::a is qiInvalid //printf("support.cpp qualifiedItemIs qiInvalid(4) returned\n"); return qiInvalid; } break; case STAR: // Like A::* // Do not allow * or ::* if (final_type_idx == 0) {// Haven't seen a type yet //printf("support.cpp qualifiedItemIs qiInvalid(5) returned\n"); return qiInvalid; } else {//printf("support.cpp qualifiedItemIs qiPtrMember returned\n"); return qiPtrMember;} case OPERATOR: // Like A::operator, ::operator, or operator //printf("support.cpp qualifiedItemIs qiOperator returned\n"); return qiOperator; default: // Something that neither starts with :: or ID, or // a :: not followed by ID, operator, ~, or * //printf("support.cpp qualifiedItemIs qiInvalid(6) returned\n"); return qiInvalid; } }
void CheckAutoVariables::autoVariables() { bool begin_function = false; bool begin_function_decl = false; int bindent = 0; for (const Token *tok = _tokenizer->tokens(); tok; tok = tok->next()) { if (Token::Match(tok, "%type% *|::| %var% (")) { begin_function = true; fp_list.clear(); vd_list.clear(); vda_list.clear(); } else if (begin_function && begin_function_decl && Token::Match(tok, "%type% * * %var%")) { fp_list.insert(tok->tokAt(3)->str()); } else if (begin_function && begin_function_decl && Token::Match(tok, "%type% * %var% [")) { fp_list.insert(tok->tokAt(2)->str()); } else if (begin_function && tok->str() == "(") { begin_function_decl = true; } else if (begin_function && tok->str() == ")") { begin_function_decl = false; } else if (begin_function && tok->str() == "{") { bindent++; } else if (begin_function && tok->str() == "}") { bindent--; } else if (bindent <= 0) { continue; } // Inside a function body if (Token::Match(tok, "%type% :: %any%") && !isExternOrStatic(tok)) { addVD(tok->tokAt(2)->varId()); } else if (Token::Match(tok, "%type% %var% [")) { addVDA(tok->next()->varId()); } else if (Token::Match(tok, "%var% %var% ;") && !isExternOrStatic(tok) && isTypeName(tok)) { addVD(tok->next()->varId()); } else if (Token::Match(tok, "const %var% %var% ;") && !isExternOrStatic(tok) && isTypeName(tok->next())) { addVD(tok->tokAt(2)->varId()); } //Critical assignment else if (Token::Match(tok, "[;{}] %var% = & %var%") && errorAv(tok->tokAt(1), tok->tokAt(4))) { errorAutoVariableAssignment(tok); } else if (Token::Match(tok, "[;{}] * %var% = & %var%") && errorAv(tok->tokAt(2), tok->tokAt(5))) { errorAutoVariableAssignment(tok); } else if (Token::Match(tok, "[;{}] %var% [ %any% ] = & %var%") && errorAv(tok->tokAt(1), tok->tokAt(7))) { errorAutoVariableAssignment(tok); } // Critical return else if (Token::Match(tok, "return & %var% ;") && isAutoVar(tok->tokAt(2)->varId())) { reportError(tok, Severity::error, "autoVariables", "Return of the address of an auto-variable"); } // Invalid pointer deallocation else if (Token::Match(tok, "free ( %var% ) ;") && isAutoVarArray(tok->tokAt(2)->varId())) { reportError(tok, Severity::error, "autoVariables", "Invalid deallocation"); } } vd_list.clear(); vda_list.clear(); fp_list.clear(); }