static void HandleX86ForceAlignArgPointerAttr(Decl *D, const AttributeList& Attr, Sema &S) { // Check the attribute arguments. if (Attr.getNumArgs() != 0) { S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; return; } // If we try to apply it to a function pointer, don't warn, but don't // do anything, either. It doesn't matter anyway, because there's nothing // special about calling a force_align_arg_pointer function. ValueDecl *VD = dyn_cast<ValueDecl>(D); if (VD && VD->getType()->isFunctionPointerType()) return; // Also don't warn on function pointer typedefs. TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D); if (TD && (TD->getUnderlyingType()->isFunctionPointerType() || TD->getUnderlyingType()->isFunctionType())) return; // Attribute can only be applied to function types. if (!isa<FunctionDecl>(D)) { S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) << Attr.getName() << /* function */0; return; } D->addAttr(::new (S.Context) X86ForceAlignArgPointerAttr(Attr.getRange(), S.Context)); }
bool FindMethodLocalVariables::VisitDeclRefExpr(DeclRefExpr* e) { switch(_state) { case LHS: { // _os << "#######: DeclRefExpr: " << getVariableName(e) << ", lvalue: " << e->getDecl()->getDeclKindName() << "\n"; // e->dumpAll(); ValueDecl* vd = e->getDecl(); if (vd == NULL) break; QualType q = vd->getType(); const Type* t = q.getTypePtr(); Decl* d = e->getDecl(); if (d == NULL) break; string declKind(d->getDeclKindName()); if ((getDataMembertype(e) == "enum sc_core::sc_time_unit") || (declKind == "CXXMethod")) { break; } string name = getVariableName(e); if ((_inMethodVariables.find(name)) != _inMethodVariables.end()) { // Found entry. break; } // _os << "=> @@@@@@@@@@@@@@@@@@@@@@@@@@@ Insert\n"; /// Prepare variable information. VariableTypeInfo v(_os); v._name = getVariableName(e); v._expr = e; v._isArray = t->isConstantArrayType(); v._type = getDataMembertype(e); if (v._isArray) { if (const ConstantArrayType* ca = dyn_cast<ConstantArrayType>(t)) { v._arraySize = ca->getSize(); } } /// Freed in the destructor of VariableTypeInfo. FindTemplateTypes te; te.Enumerate(t); v._tempArgs = te; // v.print(); _inMethodVariables.insert(kvType(v._name, v)); break; } case RHS: { //_os << "\n=> DeclRefExpr\n"; break; } }; return true; }
string NetworkDriverRewriteVisitor::GetSharedStructStr(CallExpr *callExpr) { string shared_struct_str = ""; Expr *callee = callExpr->getCallee(); if (!isa<ImplicitCastExpr>(callee)) return shared_struct_str; ImplicitCastExpr *calleeImplExpr = cast<ImplicitCastExpr>(callee); if (!isa<DeclRefExpr>(calleeImplExpr->getSubExpr())) return shared_struct_str; DeclRefExpr *calleeDeclExpr = cast<DeclRefExpr>(calleeImplExpr->getSubExpr()); Stmt *body = callExpr->getCalleeDecl()->getBody(); if (calleeDeclExpr->getNameInfo().getAsString() != "alloc_etherdev") shared_struct_str = GetSharedStructStrInFunctionBody(body, false); if (calleeDeclExpr->getNameInfo().getAsString() != "alloc_etherdev") return shared_struct_str; for (auto i = callExpr->arg_begin(), e = callExpr->arg_end(); i != e; ++i) { if (!isa<ImplicitCastExpr>(*i)) continue; ImplicitCastExpr *argImplExpr = cast<ImplicitCastExpr>(*i); if (!isa<UnaryExprOrTypeTraitExpr>(argImplExpr->getSubExpr())) continue; UnaryExprOrTypeTraitExpr *argExpr = cast<UnaryExprOrTypeTraitExpr>(argImplExpr->getSubExpr()); ParenExpr *parenExpr = cast<ParenExpr>(argExpr->getArgumentExpr()); UnaryOperator *uop = cast<UnaryOperator>(parenExpr->getSubExpr()); ImplicitCastExpr *implExpr = cast<ImplicitCastExpr>(uop->getSubExpr()); DeclRefExpr *declExpr = cast<DeclRefExpr>(implExpr->getSubExpr()); ValueDecl *valueDecl = cast<ValueDecl>(declExpr->getDecl()); shared_struct_str = valueDecl->getType().getAsString(Context->getPrintingPolicy()); break; } return shared_struct_str; }
void NetworkDriverRewriteVisitor::CreateCheckerFunction(FunctionDecl* funcDecl, string fdFile) { string device_str; Stmt *body = funcDecl->getBody(); for (auto i = body->child_begin(), e = body->child_end(); i != e; ++i) { if (!isa<DeclStmt>(*i)) continue; DeclStmt *declStmt = cast<DeclStmt>(*i); if (!declStmt->isSingleDecl() && !isa<VarDecl>(declStmt->getSingleDecl())) continue; VarDecl *varDecl = cast<VarDecl>(declStmt->getSingleDecl()); if (!isa<ValueDecl>(varDecl)) continue; ValueDecl *value = cast<ValueDecl>(varDecl); if (value->getType().getAsString(Context->getPrintingPolicy()) != "struct net_device *") continue; if (!isa<NamedDecl>(varDecl)) continue; NamedDecl *named = cast<NamedDecl>(varDecl); device_str = named->getNameAsString(); break; } if (device_str.empty()) return; string shared_struct_str = GetSharedStructStrInFunctionBody(body, true); if (shared_struct_str.empty()) return; FileID fileId = Context->getSourceManager().getFileID(funcDecl->getLocation()); SourceLocation loc = Context->getSourceManager().getLocForEndOfFile(fileId); RW.InsertText(loc, "\n", true, true); RW.InsertText(loc, "void whoop$checker(", true, true); map<string, string> func_params; for (auto i = funcDecl->param_begin(), e = funcDecl->param_end(); i != e; ++i) { ValueDecl *paramVal = cast<ValueDecl>(*i); NamedDecl *paramNam = cast<NamedDecl>(*i); string paramType = paramVal->getType().getAsString(Context->getPrintingPolicy()); string paramName = paramNam->getNameAsString(); func_params[paramType] = paramName; if (i == funcDecl->param_begin()) RW.InsertText(loc, paramType + " " + paramName + ", ", true, true); else RW.InsertText(loc, paramType + " " + paramName, true, true); } RW.InsertText(loc, ")\n", true, true); RW.InsertText(loc, "{\n", true, true); RW.InsertText(loc, "\tstruct net_device *dev;\n", true, true); RW.InsertText(loc, "\t" + shared_struct_str + "shared;\n", true, true); RW.InsertText(loc, "\tdev = alloc_etherdev(sizeof(*shared));\n\n", true, true); RW.InsertText(loc, "\tstruct sk_buff *whoop_skb = (struct sk_buff *) malloc(sizeof(struct sk_buff));\n", true, true); RW.InsertText(loc, "\tstruct ethtool_wolinfo *whoop_wolinfo = (struct ethtool_wolinfo *) malloc(sizeof(struct ethtool_wolinfo));\n", true, true); RW.InsertText(loc, "\tstruct ethtool_cmd *whoop_ecmd = (struct ethtool_cmd *) malloc(sizeof(struct ethtool_cmd));\n", true, true); RW.InsertText(loc, "\tstruct ifreq *whoop_ifreq = (struct ifreq *) malloc(sizeof(struct ifreq));\n", true, true); RW.InsertText(loc, "\tstruct rtnl_link_stats64 *whoop_rtnlsts64 = (struct rtnl_link_stats64 *) malloc(sizeof(struct rtnl_link_stats64));\n", true, true); RW.InsertText(loc, "\tstruct ethtool_regs *whoop_ethtoolregs = (struct ethtool_regs *) malloc(sizeof(struct ethtool_regs));\n", true, true); RW.InsertText(loc, "\tstruct ethtool_stats *whoop_ethtoolsts = (struct ethtool_stats *) malloc(sizeof(struct ethtool_stats));\n", true, true); RW.InsertText(loc, "\tstruct ethtool_drvinfo *whoop_ethtooldrvinfo = (struct ethtool_drvinfo *) malloc(sizeof(struct ethtool_drvinfo));\n", true, true); RW.InsertText(loc, "\tnetdev_features_t whoop_netdevfeat = NETIF_F_RXCSUM;\n\n", true, true); RW.InsertText(loc, "\tint whoop_int = __SMACK_nondet();\n", true, true); RW.InsertText(loc, "\t__SMACK_code(\"assume @ >= @;\", whoop_int, 0);\n\n", true, true); auto entry_points = DI->getInstance().GetEntryPoints(); for(auto i = entry_points.rbegin(); i != entry_points.rend(); i++) { string entry_point_call; entry_point_call = "" + i->first + "("; if (find(i->second.begin(), i->second.end(), "struct net_device *") == i->second.end()) entry_point_call += device_str + ", "; for(auto j = i->second.begin(); j != i->second.end(); j++) { if (*j == "struct net_device *") entry_point_call += device_str + ", "; else if (*j == "struct pci_dev *") entry_point_call += func_params["struct pci_dev *"] + ", "; else if (*j == "struct device *") entry_point_call += "&" + func_params["struct pci_dev *"] + "->dev, "; else if (*j == "void *") entry_point_call += "NULL, "; else if (*j == "u64 *") entry_point_call += "NULL, "; else if (*j == "u8 *") entry_point_call += "NULL, "; else if (*j == "struct sk_buff *") entry_point_call += "whoop_skb, "; else if (*j == "struct ethtool_wolinfo *") entry_point_call += "whoop_wolinfo, "; else if (*j == "struct ethtool_cmd *") entry_point_call += "whoop_ecmd, "; else if (*j == "struct ifreq *") entry_point_call += "whoop_ifreq, "; else if (*j == "struct rtnl_link_stats64 *") entry_point_call += "whoop_rtnlsts64, "; else if (*j == "struct ethtool_regs *") entry_point_call += "whoop_ethtoolregs, "; else if (*j == "struct ethtool_stats *") entry_point_call += "whoop_ethtoolsts, "; else if (*j == "struct ethtool_drvinfo *") entry_point_call += "whoop_ethtooldrvinfo, "; else if (*j == "netdev_features_t") entry_point_call += "whoop_netdevfeat, "; else if (*j == "int") entry_point_call += "whoop_int, "; else if (*j == "u32") entry_point_call += "whoop_int, "; else entry_point_call += *j + ", "; } entry_point_call.resize(entry_point_call.size() - 2); RW.InsertText(loc, "\t" + entry_point_call + ");\n", true, true); } RW.InsertText(loc, "}", true, true); }
string NetworkDriverRewriteVisitor::GetSharedStructStrInFunctionBody(Stmt *body, bool doLog) { string shared_struct_str = ""; for (auto i = body->child_begin(), e = body->child_end(); i != e; ++i) { if (isa<DeclStmt>(*i)) { DeclStmt *declStmt = cast<DeclStmt>(*i); if (!declStmt->isSingleDecl() && !isa<VarDecl>(declStmt->getSingleDecl())) continue; VarDecl *varDecl = cast<VarDecl>(declStmt->getSingleDecl()); if (!isa<ValueDecl>(varDecl)) continue; ValueDecl *value = cast<ValueDecl>(varDecl); if (value->getType().getAsString(Context->getPrintingPolicy()) != "struct net_device *") continue; if (!isa<NamedDecl>(varDecl)) continue; if (varDecl->getInit() == 0 || !isa<CallExpr>(varDecl->getInit())) continue; CallExpr *callExpr = cast<CallExpr>(varDecl->getInit()); shared_struct_str = GetSharedStructStr(callExpr); if (shared_struct_str != "") { if (doLog) { Expr *callee = callExpr->getCallee(); ImplicitCastExpr *calleeImplExpr = cast<ImplicitCastExpr>(callee); DeclRefExpr *calleeDeclExpr = cast<DeclRefExpr>(calleeImplExpr->getSubExpr()); DI->getInstance().AddSharedStructInformation("whoop_network_shared_struct", calleeDeclExpr->getNameInfo().getAsString()); } break; } } else if (isa<BinaryOperator>(*i)) { BinaryOperator *binOp = cast<BinaryOperator>(*i); if (!isa<CallExpr>(binOp->getRHS())) continue; CallExpr *callExpr = cast<CallExpr>(binOp->getRHS()); shared_struct_str = GetSharedStructStr(callExpr); if (shared_struct_str != "") { if (doLog) { Expr *callee = callExpr->getCallee(); ImplicitCastExpr *calleeImplExpr = cast<ImplicitCastExpr>(callee); DeclRefExpr *calleeDeclExpr = cast<DeclRefExpr>(calleeImplExpr->getSubExpr()); DI->getInstance().AddSharedStructInformation("whoop_network_shared_struct", calleeDeclExpr->getNameInfo().getAsString()); } break; } } } return shared_struct_str; }
void USBDriverRewriteVisitor::CreateCheckerFunction(FunctionDecl* funcDecl, string fdFile) { string device_str; string shared_struct_str; FileID fileId = Context->getSourceManager().getFileID(funcDecl->getLocation()); SourceLocation loc = Context->getSourceManager().getLocForEndOfFile(fileId); RW.InsertText(loc, "\n", true, true); RW.InsertText(loc, "void whoop$checker(", true, true); map<string, string> func_params; for (auto i = funcDecl->param_begin(), e = funcDecl->param_end(); i != e; ++i) { if (i != funcDecl->param_begin()) RW.InsertText(loc, ", ", true, true); ValueDecl *paramVal = cast<ValueDecl>(*i); NamedDecl *paramNam = cast<NamedDecl>(*i); string paramType = paramVal->getType().getAsString(Context->getPrintingPolicy()); string paramName = paramNam->getNameAsString(); func_params[paramType] = paramName; RW.InsertText(loc, paramType + " " + paramName, true, true); } RW.InsertText(loc, ")\n", true, true); RW.InsertText(loc, "{\n", true, true); RW.InsertText(loc, "\tstruct tty_struct *whoop_tty_struct = (struct tty_struct *) malloc(sizeof(struct tty_struct));\n", true, true); RW.InsertText(loc, "\tstruct usb_serial *whoop_usb_serial = (struct usb_serial *) malloc(sizeof(struct usb_serial));\n", true, true); RW.InsertText(loc, "\tstruct usb_serial_port *whoop_usb_serial_port = (struct usb_serial_port *) malloc(sizeof(struct usb_serial_port));\n", true, true); RW.InsertText(loc, "\tstruct usb_interface *whoop_usb_interface = (struct usb_interface *) malloc(sizeof(struct usb_interface));\n", true, true); RW.InsertText(loc, "\tstruct ktermios *whoop_ktermios = (struct ktermios *) malloc(sizeof(struct ktermios));\n", true, true); RW.InsertText(loc, "\tstruct urb *whoop_urb = (struct urb *) malloc(sizeof(struct urb));\n", true, true); RW.InsertText(loc, "\tconst char *whoop_buf = (char *) malloc(sizeof(char));\n\n", true, true); RW.InsertText(loc, "\tint whoop_int = __SMACK_nondet();\n", true, true); RW.InsertText(loc, "\t__SMACK_code(\"assume @ >= @;\", whoop_int, 0);\n\n", true, true); auto entry_points = DI->getInstance().GetEntryPoints(); for(auto i = entry_points.rbegin(); i != entry_points.rend(); i++) { string entry_point_call; entry_point_call = "" + i->first + "("; for(auto j = i->second.begin(); j != i->second.end(); j++) { if (*j == "void") entry_point_call += ""; else if (*j == "void *") entry_point_call += "NULL, "; else if (*j == "u64 *") entry_point_call += "NULL, "; else if (*j == "u8 *") entry_point_call += "NULL, "; else if (*j == "struct tty_struct *") entry_point_call += "whoop_tty_struct, "; else if (*j == "struct usb_serial *") entry_point_call += "whoop_usb_serial, "; else if (*j == "struct usb_serial_port *") entry_point_call += "whoop_usb_serial_port, "; else if (*j == "struct usb_interface *") entry_point_call += "whoop_usb_interface, "; else if (*j == "struct urb *") entry_point_call += "whoop_ktermios, "; else if (*j == "struct ktermios *") entry_point_call += "whoop_urb, "; else if (*j == "char *") entry_point_call += "whoop_buf, "; else if (*j == "const char *") entry_point_call += "whoop_buf, "; else if (*j == "size_t") entry_point_call += "whoop_int, "; else if (*j == "int") entry_point_call += "whoop_int, "; else if (*j == "unsigned int") entry_point_call += "whoop_int, "; else if (*j == "long") entry_point_call += "whoop_int, "; else if (*j == "unsigned long") entry_point_call += "whoop_int, "; else if (*j == "u32") entry_point_call += "whoop_int, "; else if (*j == "fmode_t") entry_point_call += "whoop_int, "; else entry_point_call += *j + ", "; } if (entry_point_call != i->first + "(") { entry_point_call.resize(entry_point_call.size() - 2); } RW.InsertText(loc, "\t" + entry_point_call + ");\n", true, true); } RW.InsertText(loc, "}", true, true); }
/* this helper function is called when the traversal reaches a node of type Stmt */ void StmtHelper(Stmt *x){ //variable used for <cond> </cond> //bool condition = false; bool isElse = false; if(x != NULL){ string output = ""; //find current level and next level int intLevel = getLevelStmt(x); int intNextLevel = intLevel+1; //convert them both to strings to use for output string level; string nextLevel; stringstream ss; ss << intLevel; level = ss.str(); stringstream ss2; ss2 << intNextLevel; nextLevel = ss2.str(); const Stmt* parent = getStmtParent(x, Context); //PROBLEM if(x->getStmtClassName() != std::string("ForStmt") && isFlowControl(x, Context)){ //return; } //if the parent is calling any type of funciton then this node should be enclosed in <args> </args> string filename; if(callStackDebug && !callStack.empty()){ cerr << "stmt: call stack top: " << callStack.top()->getStmtClassName() << endl; } while(!callStack.empty() && numClosingArgsNeeded > 0 && !isParentStmt(parent, callStack.top()->getStmtClassName())){ if(debugPrint){ cerr << "adding args" << endl; } numClosingArgsNeeded--; output += "</args,1>\n"; callStack.pop(); if(callStackDebug){ cerr << "popping" << endl; printCallStack(); } } if(isParentStmtInCurFile(x,"CXXConstructExpr") && isParentStmt(x, "CXXConstructExpr")){ if(debugPrint){ cerr << "setting previousConstructorCall to true" << endl; } }else if(isParentStmtInCurFile(x,"CXXTemporaryObjectExpr") && isParentStmt(x, "CXXTemporaryObjectExpr")){ if(debugPrint){ cerr << "setting previousTempConstructorCallArg" << endl; } }else if(isParentStmt(x, "CallExpr")){ if(debugPrint){ cerr << "setting previousCallArgs to true" << endl; } }else if(isParentStmt(x, "CXXMemberCallExpr")){ if(debugPrint){ cerr << "setting previousMemberCallArgs to true" << endl; } } //if the parent is a variable declaration then this node should be encolsed in <decl> </decl> if(isParentStmt(x, "Var")){ previousRhsDecl = true; if(debugPrint){ cout << "setting prev var to true" << endl; } }else if(previousRhsDecl && numClosingVarsNeeded > 0){ //if the current node is not a child of a variable declaration //but the previous node was a child of a variable declation //then we know to print a </decl> output +="</variableDecl,1>\n"; numClosingVarsNeeded--; previousRhsDecl = false; } if(parent != NULL && strcmp(parent->getStmtClassName(), "IfStmt") == 0){ if(debugPrint){ cerr << "possibly an if statement" << endl; } //find the first child of the if statemt const Stmt* firstChild = NULL; auto children = parent->children(); for(const Stmt* child : children){ if(child != NULL){ firstChild = child; break; } } //if the first child is the current node, then we know it is part of the condition if(firstChild != NULL && x->getLocStart() == firstChild->getLocStart()){ if(debugPrint){ cerr << "part of the condition" << endl; } prevCondition = true; }else if(prevCondition){ output +="</cond,1>\n"; prevCondition = false; } //find if else const IfStmt* ifstmt = (IfStmt*) parent; const Stmt* elseStmt = ifstmt->getElse(); if(elseStmt != NULL){ if(debugPrint){ cout << "checking if " << x->getLocStart().printToString(Context->getSourceManager()); cout << " == " << elseStmt->getLocStart().printToString(Context->getSourceManager()); cout << " : " << (x->getLocStart() == elseStmt->getLocStart()) << endl; } if(x->getLocStart() == elseStmt->getLocStart()){ isElse = true; } } } string node = x->getStmtClassName(); if(node == "ReturnStmt"){ output += "<return"; }else if(node == "ForStmt"){ output += "<forLoop"; }else if(node == "WhileStmt"){ output += "<whileLoop"; }else if(node == "DoStmt"){ output += "<do"; }else if(node == "IfStmt"){ if(parent->getStmtClassName() != std::string("IfStmt")){ stringstream ssminus; ssminus << (intLevel-1); output += "<ifBlock," + ssminus.str() + ">\n"; intLevel += 1; stringstream ssif; ssif << intLevel; level = ssif.str(); } output += "<ifStatement"; }else if(node == "SwitchStmt"){ output += "<switch"; }else if(node == "CaseStmt"){ output += "<case"; }else if(node == "CXXMemberCallExpr"){ CXXMemberCallExpr* ce = (CXXMemberCallExpr*) x; Expr* obj = ce->getImplicitObjectArgument(); CallExpr* expr = (CallExpr*) x; output += "<object: "; QualType qt = obj->getType(); output += qt.getBaseTypeIdentifier()->getName().str(); output += "; calling func: "; output += expr->getDirectCallee()->getNameInfo().getAsString(); output += ", " + level + ">\n"; output += "<args"; numClosingArgsNeeded++; callStack.push(x); if(callStackDebug){ cerr << "pushing" << endl; printCallStack(); } }else if(node == "CallExpr"){ CallExpr* expr = (CallExpr*) x; output += "<calling func: "; output += expr->getDirectCallee()->getNameInfo().getAsString(); output += ", " + level + ">\n"; output += "<args"; numClosingArgsNeeded++; callStack.push(x); if(callStackDebug){ cerr << "pushing" << endl; printCallStack(); } }else if(node == "CXXConstructExpr"){ CXXConstructExpr* ce = (CXXConstructExpr*) x; //Decl* CD = ce->getConstructor(); string filename; //if(isInCurFile(Context, CD, filename)){ CXXMethodDecl* MD = ce->getConstructor(); output += "<calling func: "; output += MD->getNameInfo().getAsString(); output += "," + level + ">\n"; output += "<args"; numClosingArgsNeeded++; callStack.push(x); if(callStackDebug){ cerr << "pushing" << endl; printCallStack(); } //} }else if(node == "BinaryOperator"){ BinaryOperator* binaryOp = (BinaryOperator*) x; if(binaryOp->isAssignmentOp()){ output += "<assignment"; }else if(binaryOp->isComparisonOp()){ output += "<comparison"; }else{ output += "<binaryOp"; } }else if(node == "UnaryOperator"){ UnaryOperator* uo = (UnaryOperator*) x; string op = uo->getOpcodeStr(uo->getOpcode()).str(); if(op != "-"){ output += "<unaryOp"; } }else if(node == "CompoundAssignOperator"){ output += "<augAssign"; }else if(node == "CompoundStmt"){ if(isElse){ output += "<elseStatement"; }else{ output += "<compoundStmt"; } }else if(node == "CXXThrowExpr"){ output += "<raisingException"; }else if(node == "CXXTryStmt"){ output += "<try"; }else if(node == "CXXCatchStmt"){ output += "<except"; }else if(node == "CXXOperatorCallExpr"){ CXXOperatorCallExpr* ce = (CXXOperatorCallExpr*) x; if(ce->isAssignmentOp()){ output += "<assignment"; } }else if(node == "CXXTemporaryObjectExpr"){ CXXTemporaryObjectExpr* ce = (CXXTemporaryObjectExpr*) x; Decl* CD = ce->getConstructor(); string filename; if(isInCurFile(Context, CD, filename)){ CXXMethodDecl* MD = ce->getConstructor(); output += "<calling func: "; output += MD->getNameInfo().getAsString(); output += "," + level + ">\n"; output += "<args"; numClosingArgsNeeded++; callStack.push(x); if(callStackDebug){ cerr << "pushing" << endl; printCallStack(); } } }else if(node == "DeclRefExpr"){ if(parent != NULL && parent->getStmtClassName() == std::string("ImplicitCastExpr")){ DeclRefExpr* dr = (DeclRefExpr*) x; ValueDecl* d = (ValueDecl*) dr->getDecl(); //cout << d->getQualType().getAsString() << endl; if(d != NULL){ QualType qt = d->getType(); //cout << qt.getAsString() << endl; if(qt.getAsString() == "std::vector<int, class std::allocator<int> >::const_reference (std::vector::size_type) const noexcept"){ //string type = io->getName().str(); //cout << type << endl; //if(type == "vector"){ output += "<expr"; //} } } } }else{ if(allNodes){ output += "<"; output += node; output += ">"; } } if(output.size() != 0 && !endsIn(output, "</cond,1>\n") && !endsIn(output,"</variableDecl,1>\n") && !endsIn(output,"</args,1>\n") && !endsIn(output,">") && !endsIn(output, ">\n")){ output += ", " + level + ">"; cout << output << endl; output = ""; }else if(output.size() != 0){ cout << output << endl; output = ""; if(debugPrint){ cerr << "printing output" << endl; } } } }