Пример #1
0
// Traverse VAR DECL
bool SuperastCPP::TraverseVarDecl(clang::VarDecl* var) {
  const std::string varName = var->getName().str();

  rapidjson::Value varValue(rapidjson::kObjectType);
  addId(varValue);
  addPos(varValue, var);

  // Variable Declaration if it is not a parameter of a function
  if (!clang::dyn_cast<clang::ParmVarDecl>(var)) {
    varValue.AddMember("type", "variable-declaration", allocator);
  }
  
  varValue.AddMember("name", 
                     rapidjson::Value().SetString(varName.c_str(), 
                                                  varName.size(), 
                                                  allocator), 
                     allocator);

  // NonLValueExpr to remove LValueExpression for references. 
  // There are more options
  clang::QualType qualType = var->getType().getNonLValueExprType(*context);
  const clang::Type* type = qualType.getTypePtr();
  bool isConst = var->getType().isConstQualified() | qualType.isConstQualified();

  //std::cerr << " type: " << type->getCanonicalTypeInternal().getAsString();
  varValue.AddMember("data-type", createTypeValue(type), allocator);
  varValue.AddMember("is-reference", var->getType()->isReferenceType(), allocator);
  varValue.AddMember("is-const", isConst, allocator);
  

  if (var->hasInit() && !type->isStructureType() && 
      !isSTLVectorType(type->getCanonicalTypeInternal())) {
    rapidjson::Value exprValue(rapidjson::kObjectType);
    TRY_TO(TraverseStmt(var->getInit()));

    clang::VarDecl::InitializationStyle initStyle = var->getInitStyle();
    switch (initStyle) {
      case clang::VarDecl::CInit:
      case clang::VarDecl::CallInit:
        // We don't distinguis between these two initializations
        if (!sonValue.IsNull()) {
          varValue.AddMember("init", sonValue, allocator);
        }
        // Call style initializer (int x(1))
        break;
      case clang::VarDecl::ListInit:
        // C++11 Initializer list. Not supported by us.
        break;
    }
  }

  sonValue = varValue;
  return true;
}
Пример #2
0
  // IF STATEMENT 
bool SuperastCPP::TraverseIfStmt(clang::IfStmt* ifs) {
  rapidjson::Value ifValue(rapidjson::kObjectType);
  addId(ifValue);
  addPos(ifValue, ifs);
  ifValue.AddMember("type", "conditional", allocator);

  // Check if the condition contains a var declaration
  if (ifs->getConditionVariable()) {
    ifValue.AddMember("condition", createMessageValue(ifs->getConditionVariable(), "error",
        "condition-variable",
        "Variable declarations are not allowed in if conditions"),
        allocator);
  }
  else {
    // condition part
    TRY_TO(TraverseStmt(ifs->getCond()));

    rapidjson::Value conditionValue;
    conditionValue = sonValue;
    ifValue.AddMember("condition", conditionValue, allocator);
  }

  // then part
  TRY_TO(TraverseStmt(ifs->getThen()));
  // Now sonValue contains the arrayValue
  ensureSonIsArray();
  rapidjson::Value blockValue = createBlockValue(sonValue);
  ifValue.AddMember("then", blockValue, allocator);

  // if has else, print
  if (ifs->getElse()) {
    TRY_TO(TraverseStmt(ifs->getElse()));
    // sonValue contains the arrayValue
    ensureSonIsArray();
    blockValue = createBlockValue(sonValue);
    ifValue.AddMember("else", blockValue, allocator);
  }

  sonValue = ifValue;
  return true;
}
Пример #3
0
bool SuperastCPP::TraverseFunctionDecl(clang::FunctionDecl* functionDecl) {

  const std::string functionName = functionDecl->getNameInfo().getAsString();

  rapidjson::Value functionValue(rapidjson::kObjectType);
  addId(functionValue);
  addPos(functionValue, functionDecl);
  
  functionValue.AddMember("type", "function-declaration", allocator);
  // Add the name
  functionValue.AddMember(
      "name", 
      rapidjson::Value().SetString(functionName.c_str(), 
                                   functionName.size(),
                                   allocator), 
      allocator);

  // Add the return type
  clang::QualType qualType = functionDecl->getCallResultType().getNonLValueExprType(*context);
  functionValue.AddMember("return-type", createTypeValue((qualType.getTypePtr())), allocator);

  // Array of parameters
  rapidjson::Value parametersValue(rapidjson::kArrayType);

  // Traverse parameters
  for (unsigned int i = 0; i < functionDecl->param_size(); ++i) {
    TRY_TO(TraverseDecl(functionDecl->getParamDecl(i)));

    // Add the parameter to array
    parametersValue.PushBack(sonValue, allocator);
  }

  // Add parameters to functionValue
  functionValue.AddMember("parameters", parametersValue, allocator);
  
  // If this is a function definition, traverse definition.
  if (functionDecl->isThisDeclarationADefinition()) {
    TRY_TO(TraverseStmt(functionDecl->getBody()));
    ensureSonIsArray();
    rapidjson::Value blockValue = createBlockValue(sonValue);
    functionValue.AddMember("block", blockValue, allocator);
  }
  else {
    // If not definition, add empty block
    rapidjson::Value emptyArray(rapidjson::kArrayType);
    functionValue.AddMember("block", createBlockValue(emptyArray), allocator);
  }

  // END BODY TRAVERSE
  sonValue = functionValue;
  return true;
}
Пример #4
0
// RETURN STATEMENT
bool SuperastCPP::TraverseReturnStmt(clang::ReturnStmt* ret) {
  rapidjson::Value returnValue(rapidjson::kObjectType);
  addId(returnValue);
  addPos(returnValue, ret);
  
  TRY_TO(TraverseStmt(ret->getRetValue()));

  returnValue.AddMember("type", "return", allocator);
  returnValue.AddMember("expression", sonValue, allocator);

  sonValue = returnValue;
  return true;
}
Пример #5
0
// COMPOUND STATEMENTS, A block of statements in clangAST
bool SuperastCPP::TraverseCompoundStmt(clang::CompoundStmt* compoundStmt) {
  rapidjson::Value arrayValue(rapidjson::kArrayType);
  // Traverse each statement and append it to the array
  for (clang::Stmt* stmt : compoundStmt->body()) {
    TRY_TO(TraverseStmt(stmt));
    if (sonValue.IsArray()) {
      addElemsToArray(arrayValue, sonValue);
    }
    else {
      arrayValue.PushBack(sonValue, allocator);
    }
  }
  sonValue = arrayValue;
  return true;
}
Пример #6
0
  bool DoTraverseStmt(clang::Stmt *S) {
    if (auto const E = llvm::dyn_cast<clang::CallExpr>(S)) {
      // If this is a direct function call, don't bother showing the nodes for
      // the DeclRefExpr and function to pointer decay - just show arg nodes.
      if (E->getDirectCallee()) {
        for (auto const &Arg : seec::range(E->arg_begin(), E->arg_end())) {
          if (!TraverseStmt(Arg))
            return false;
        }

        return true;
      }
    }

    return clang::RecursiveASTVisitor<DepthRecorder>::TraverseStmt(S);
  }
Пример #7
0
void VarCollector::HandleDirective(PragmaDirectiveMap *Directives,
                                   DirectiveList *FullDirectives,
                                   FullDirective *FD) {

  this->Directives = Directives;
  this->FullDirectives = FullDirectives;

  FullDirectives->ResetStack();

  FullDirectives->Push(FD->Directive, FD->Header, FD->S, *(FD->CI));

  CompilerInstanceStack.push_back(FD->CI);

  TraverseStmt(FD->S);

  CompilerInstanceStack.pop_back();

}
Пример #8
0
 void Fix(CompoundStmt* CS) {
   if (!CS->size())
     return;
   typedef llvm::SmallVector<Stmt*, 32> Statements;
   Statements Stmts;
   Stmts.append(CS->body_begin(), CS->body_end());
   for (Statements::iterator I = Stmts.begin(); I != Stmts.end(); ++I) {
     if (!TraverseStmt(*I) && !m_HandledDecls.count(m_FoundDRE->getDecl())) {
       Sema::DeclGroupPtrTy VDPtrTy 
         = m_Sema->ConvertDeclToDeclGroup(m_FoundDRE->getDecl());
       StmtResult DS = m_Sema->ActOnDeclStmt(VDPtrTy, 
                                             m_FoundDRE->getLocStart(), 
                                             m_FoundDRE->getLocEnd());
       assert(!DS.isInvalid() && "Invalid DeclStmt.");
       I = Stmts.insert(I, DS.take());
       m_HandledDecls.insert(m_FoundDRE->getDecl());
     }
   }
   CS->setStmts(m_Sema->getASTContext(), Stmts.data(), Stmts.size());
 }
Пример #9
0
bool VarCollector::VisitCallExpr(CallExpr *e) {

  FunctionCall * FC = FullDirectives->Push(e);

  if (!FC) {
    CompilerInstance &CI = *(CompilerInstanceStack.back());
    DiagnosticsEngine &Diags = CI.getDiagnostics();

    unsigned DiagID =
        Diags.getCustomDiagID(DiagnosticsEngine::Warning,
                              "Call to function '%0' does not have a "
                              "definition, hence cannot be checked for safety");
    Diags.Report(e->getLocStart(), DiagID) << e->getDirectCallee()->getName();

  } else {
    CompilerInstanceStack.push_back(FC->CI);
    TraverseStmt(FC->S);
    CompilerInstanceStack.pop_back();
  }

  return true;

}
 bool findBreak(SwitchCase *switchCaseStmt)
 {
     return !TraverseStmt(switchCaseStmt);
 }
Пример #11
0
bool SuperastCPP::TraverseCXXOperatorCallExpr(clang::CXXOperatorCallExpr* operatorCallExpr) {
  // IF THERE IS A PRINT
  auto decl = llvm::dyn_cast<clang::FunctionDecl>(operatorCallExpr->getCalleeDecl());
  if (!decl) {
    std::cerr << "Unknown function in CXXOperatorCallExpr" << std::endl;
    return true;
  }
  const std::string functionName = decl->getNameInfo().getAsString();
  if (functionName == PRINT_NAME || functionName == READ_NAME) {
    bool isFirst = false;
    if (!iofunctionStarted) {
      isFirst = true;
      iofunctionStarted = true;
    }

    rapidjson::Value arrayValue(rapidjson::kArrayType);
    for (unsigned i = 0; i < operatorCallExpr->getNumArgs(); ++i) {
      TRY_TO(TraverseStmt(operatorCallExpr->getArg(i)));
      if (i == 0) {
        // If sonValue is not an array, is because it reached the begin of
        // call, which is the cout/cerr/stream class
        if (sonValue.IsArray()) {
          arrayValue = sonValue;
        }
      }
      else {
        arrayValue.PushBack(sonValue, allocator);
      }
    }
    
    if (!isFirst) {
      sonValue = arrayValue;
    }
    else {
      iofunctionStarted = false;

      rapidjson::Value functionValue(rapidjson::kObjectType);
      addId(functionValue);
      addPos(functionValue, operatorCallExpr);
      functionValue.AddMember("type", "function-call", allocator);
      if (functionName == PRINT_NAME) 
        functionValue.AddMember("name", "print", allocator);
      else functionValue.AddMember("name", "read", allocator);
      functionValue.AddMember("arguments", arrayValue, allocator);
      sonValue = functionValue;
    }
  }
  else if (functionName == VECTOR_POS_NAME) {
    // Operator []
    TRY_TO(TraverseStmt(operatorCallExpr->getArg(0)));
    rapidjson::Value leftValue(rapidjson::kObjectType);
    leftValue = sonValue;
    TRY_TO(TraverseStmt(operatorCallExpr->getArg(1)));
    rapidjson::Value rightValue(rapidjson::kObjectType);
    rightValue = sonValue;
    sonValue = createBinOpValue("[]", leftValue, rightValue);
  }
  else {
    std::cerr << "Operator call not defined: " << functionName << std::endl;
  }
    return true;
}
Пример #12
0
 StatementVisitor(const clang::Stmt *const stmt) : stmt_{stmt} {
     TraverseStmt(const_cast<clang::Stmt *>(stmt_));
 }
Пример #13
0
void DeclReferencer::Traverse(Loc loc, Scope *sc, clang::Stmt *S)
{
    this->loc = loc;
    this->sc = sc;
    TraverseStmt(S);
}
 void extract(ObjCAtFinallyStmt *finallyStmt, vector<ObjCMessageExpr*> *raisers)
 {
     _raisers = raisers;
     (void) /* explicitly ignore the return of this function */ TraverseStmt(finallyStmt);
 }
 void extract(ObjCAtFinallyStmt *finallyStmt, vector<ObjCAtThrowStmt*> *throws)
 {
     _throws = throws;
     (void) /* explicitly ignore the return of this function */ TraverseStmt(finallyStmt);
 }
Пример #16
0
 void Fix(CompoundStmt* CS) {
   TraverseStmt(CS);
 }