ASTConsumer *InsertBracesFrontendAction::CreateASTConsumer(
    CompilerInstance &Compiler, StringRef InFile) {
  
  ASTContext *ctx = &Compiler.getASTContext();
  rewriter = Rewriter(ctx->getSourceManager(), ctx->getLangOpts());
  return new InsertBracesASTConsumer(rewriter);
}
Пример #2
0
    bool VisitCallExpr(CallExpr *E) {
        llvm::errs() << "I see a CallExpr\n";
        E->dump();


        Expr *callee = E->getCallee();

        if (ImplicitCastExpr *ica = llvm::dyn_cast<ImplicitCastExpr>(callee)) {
            callee = ica->getSubExpr();
        }

        if (DeclRefExpr *dref = llvm::dyn_cast<DeclRefExpr>(callee)) {
            llvm::errs() << "declref:\n";
            dref->dump();

            NamedDecl *d = dref->getFoundDecl();
            ASTContext &Context = d->getASTContext();
            SourceManager &SM = Context.getSourceManager();

            if (dref->hasQualifier()) {
                llvm::errs() << "  has qualifier in name.\n";
                NestedNameSpecifierLoc lc = dref->getQualifierLoc();

                llvm::errs() << "    begin loc: " << lc.getBeginLoc().printToString(SM)
                             << "\n";
                llvm::errs() << "    end loc: " << lc.getEndLoc().printToString(SM)
                             << "\n";
            }

            if (UsingShadowDecl *sh = llvm::dyn_cast<UsingShadowDecl>(d)) {
                NamedDecl *td = sh->getTargetDecl();
                FoundRealDecl(td);
                //d->dump();
            } else {
                FoundRealDecl(d);
                //d->dump();
            }
        } else if (UnresolvedLookupExpr *ule = dyn_cast<UnresolvedLookupExpr>(callee)) {
            llvm::errs() << "unresolved\n";
            ASTContext* Context;
            SourceManager* SM;
            for (const auto *d : ule->decls()) {
                FoundRealDecl(d);
                Context = &d->getASTContext();
                SM = &Context->getSourceManager();
            }
            llvm::errs() << "    begin loc: " << ule->getLocStart().printToString(*SM)
                         << "\n";
            llvm::errs() << "    end loc: " << ule->getLocEnd().printToString(*SM)
                         << "\n";

            NestedNameSpecifierLoc ll = ule->getQualifierLoc();
            llvm::errs() << "    nested begin loc: "
                         << ll.getBeginLoc().printToString(*SM) << "\n";
            llvm::errs() << "    nested end loc: "
                         << ll.getEndLoc().printToString(*SM) << "\n";
        }

        return true;
    }
Пример #3
0
/// \brief \arg Loc is the end of a statement range. This returns the location
/// of the token of expected type following the statement.
/// If no token of this type is found or the location is inside a macro, the returned
/// source location will be invalid.
SourceLocation findTokenAfterLocation(SourceLocation loc, ASTContext& Ctx,
        tok::TokenKind tokenType)
{
    SourceManager &SM = Ctx.getSourceManager();
    if (loc.isMacroID()) {
        if (!Lexer::isAtEndOfMacroExpansion(loc, SM, Ctx.getLangOpts(), &loc))
            return SourceLocation();
    }
    loc = Lexer::getLocForEndOfToken(loc, /*Offset=*/0, SM, Ctx.getLangOpts());

    // Break down the source location.
    std::pair<FileID, unsigned> locInfo = SM.getDecomposedLoc(loc);

    // Try to load the file buffer.
    bool invalidTemp = false;
    StringRef file = SM.getBufferData(locInfo.first, &invalidTemp);
    if (invalidTemp)
        return SourceLocation();

    const char *tokenBegin = file.data() + locInfo.second;

    // Lex from the start of the given location.
    Lexer lexer(SM.getLocForStartOfFile(locInfo.first), Ctx.getLangOpts(),
            file.begin(), tokenBegin, file.end());
    Token tok;
    lexer.LexFromRawLexer(tok);
    if (tok.isNot(tokenType))
        return SourceLocation();

    return tok.getLocation();
}
Пример #4
0
  void HandleTranslationUnit(ASTContext &Context) override {
    const auto &SourceMgr = Context.getSourceManager();
    std::vector<SourceLocation> RenamingCandidates;
    std::vector<SourceLocation> NewCandidates;

    for (const auto &USR : USRs) {
      NewCandidates = getLocationsOfUSR(USR, Context.getTranslationUnitDecl());
      RenamingCandidates.insert(RenamingCandidates.end(), NewCandidates.begin(),
                                NewCandidates.end());
      NewCandidates.clear();
    }

    auto PrevNameLen = PrevName.length();
    if (PrintLocations)
      for (const auto &Loc : RenamingCandidates) {
        FullSourceLoc FullLoc(Loc, SourceMgr);
        errs() << "clang-rename: renamed at: " << SourceMgr.getFilename(Loc)
               << ":" << FullLoc.getSpellingLineNumber() << ":"
               << FullLoc.getSpellingColumnNumber() << "\n";
        Replaces.insert(tooling::Replacement(SourceMgr, Loc, PrevNameLen,
                                             NewName));
      }
    else
      for (const auto &Loc : RenamingCandidates)
        Replaces.insert(tooling::Replacement(SourceMgr, Loc, PrevNameLen,
                                             NewName));
  }
Пример #5
0
  void HandleOneRename(ASTContext &Context, const std::string &NewName,
                       const std::string &PrevName,
                       const std::vector<std::string> &USRs) {
    const SourceManager &SourceMgr = Context.getSourceManager();

    SymbolOccurrences Occurrences = tooling::getOccurrencesOfUSRs(
        USRs, PrevName, Context.getTranslationUnitDecl());
    if (PrintLocations) {
      for (const auto &Occurrence : Occurrences) {
        FullSourceLoc FullLoc(Occurrence.getNameRanges()[0].getBegin(),
                              SourceMgr);
        errs() << "clang-rename: renamed at: " << SourceMgr.getFilename(FullLoc)
               << ":" << FullLoc.getSpellingLineNumber() << ":"
               << FullLoc.getSpellingColumnNumber() << "\n";
      }
    }
    // FIXME: Support multi-piece names.
    // FIXME: better error handling (propagate error out).
    StringRef NewNameRef = NewName;
    Expected<std::vector<AtomicChange>> Change =
        createRenameReplacements(Occurrences, SourceMgr, NewNameRef);
    if (!Change) {
      llvm::errs() << "Failed to create renaming replacements for '" << PrevName
                   << "'! " << llvm::toString(Change.takeError()) << "\n";
      return;
    }
    convertChangesToFileReplacements(*Change, &FileToReplaces);
  }
Пример #6
0
void SynthesizeRemovalConsumer::renameLocation(SourceLocation L,
  std::string& N) {
  if (L.isMacroID()) {        
    // TODO: emit error using diagnostics
    SourceManager &SM = astContext->getSourceManager();
    if (SM.isMacroArgExpansion(L) || SM.isInSystemMacro(L)) {
      // see if it's the macro expansion we can handle
      // e.g.
      //   #define call(x) x
      //   call(y());   // if we want to rename y()
      L = SM.getSpellingLoc(L);
      
      // this falls through to the rename routine below
    }
    else {
      // if the spelling location is from an actual file that we can
      // touch, then do the replacement, but show a warning          
      SourceManager &SM = astContext->getSourceManager();
      auto SL = SM.getSpellingLoc(L);
      FullSourceLoc FSL(SL, SM);
      const FileEntry *FE = SM.getFileEntryForID(FSL.getFileID());
      if (FE) {
        llvm::errs() << "Warning: Rename attempted as a result of macro "
                     << "expansion may break things, at: " << loc(L) << "\n";            
        L = SL;
        // this falls through to the rename routine below
      }
      else {
        // cannot handle this case
        llvm::errs() << "Error: Token is resulted from macro expansion"
          " and is therefore not renamed, at: " << loc(L) << "\n";
        return;
      }
    }
  }
    
  if (shouldIgnore(L)) {
    return;
  }
    
  auto LE = preprocessor->getLocForEndOfToken(L);
  if (LE.isValid()) {        
    // getLocWithOffset returns the location *past* the token, hence -1
    auto E = LE.getLocWithOffset(-1);
    rewriter.ReplaceText(SourceRange(L, E), N);
  }
}  
Пример #7
0
    void Initialize(ASTContext &context) {
        //llvm::errs() << "initializing consumer\n";
        Context = &context;
        SM = &Context->getSourceManager();

        // Get the ID and start/end of the main file.
        MainFileID = SM->getMainFileID();
    }
Пример #8
0
static void printSourceLocation(SourceLocation loc, ASTContext &Ctx,
                                raw_ostream &OS) {
  SourceManager &SM = Ctx.getSourceManager();
  PresumedLoc PL = SM.getPresumedLoc(loc);

  OS << llvm::sys::path::filename(PL.getFilename());
  OS << ":" << PL.getLine() << ":"
            << PL.getColumn();
}
/// \brief The LoopFixer callback, which determines if loops discovered by the
/// matchers are convertible, printing information about the loops if so.
void LoopFixer::run(const MatchFinder::MatchResult &Result) {
  const BoundNodes &Nodes = Result.Nodes;
  Confidence ConfidenceLevel(TCK_Safe);
  ASTContext *Context = Result.Context;
  const ForStmt *TheLoop = Nodes.getStmtAs<ForStmt>(LoopName);

  if (!Context->getSourceManager().isFromMainFile(TheLoop->getForLoc()))
    return;

  // Check that we have exactly one index variable and at most one end variable.
  const VarDecl *LoopVar = Nodes.getDeclAs<VarDecl>(IncrementVarName);
  const VarDecl *CondVar = Nodes.getDeclAs<VarDecl>(ConditionVarName);
  const VarDecl *InitVar = Nodes.getDeclAs<VarDecl>(InitVarName);
  if (!areSameVariable(LoopVar, CondVar) || !areSameVariable(LoopVar, InitVar))
    return;
  const VarDecl *EndVar = Nodes.getDeclAs<VarDecl>(EndVarName);
  const VarDecl *ConditionEndVar =
      Nodes.getDeclAs<VarDecl>(ConditionEndVarName);
  if (EndVar && !areSameVariable(EndVar, ConditionEndVar))
    return;

  // If the end comparison isn't a variable, we can try to work with the
  // expression the loop variable is being tested against instead.
  const CXXMemberCallExpr *EndCall =
      Nodes.getStmtAs<CXXMemberCallExpr>(EndCallName);
  const Expr *BoundExpr = Nodes.getStmtAs<Expr>(ConditionBoundName);
  // If the loop calls end()/size() after each iteration, lower our confidence
  // level.
  if (FixerKind != LFK_Array && !EndVar)
    ConfidenceLevel.lowerTo(TCK_Reasonable);

  const Expr *ContainerExpr = NULL;
  bool ContainerNeedsDereference = false;
  // FIXME: Try to put most of this logic inside a matcher. Currently, matchers
  // don't allow the right-recursive checks in digThroughConstructors.
  if (FixerKind == LFK_Iterator)
    ContainerExpr = findContainer(Context, LoopVar->getInit(),
                                  EndVar ? EndVar->getInit() : EndCall,
                                  &ContainerNeedsDereference);
  else if (FixerKind == LFK_PseudoArray) {
    if (!EndCall)
      return;
    ContainerExpr = EndCall->getImplicitObjectArgument();
    const MemberExpr *Member = dyn_cast<MemberExpr>(EndCall->getCallee());
    if (!Member)
      return;
    ContainerNeedsDereference = Member->isArrow();
  }
  // We must know the container or an array length bound.
  if (!ContainerExpr && !BoundExpr)
    return;

  findAndVerifyUsages(Context, LoopVar, EndVar, ContainerExpr, BoundExpr,
                      ContainerNeedsDereference, TheLoop, ConfidenceLevel);
}
Пример #10
0
 void HandleTranslationUnit(ASTContext &Context) override {
   const SourceManager &SourceMgr = Context.getSourceManager();
   for (unsigned Offset : SymbolOffsets) {
     if (!FindSymbol(Context, SourceMgr, Offset, ""))
       return;
   }
   for (const std::string &QualifiedName : QualifiedNames) {
     if (!FindSymbol(Context, SourceMgr, 0, QualifiedName))
       return;
   }
 }
Пример #11
0
    void HandleInlineMethodDefinition(CXXMethodDecl *D) override {
      PrettyStackTraceDecl CrashInfo(D, SourceLocation(),
                                     Context->getSourceManager(),
                                     "LLVM IR generation of inline method");
      if (llvm::TimePassesIsEnabled)
        LLVMIRGeneration.startTimer();

      Gen->HandleInlineMethodDefinition(D);

      if (llvm::TimePassesIsEnabled)
        LLVMIRGeneration.stopTimer();
    }
Пример #12
0
  // This gets called only when the full TU is completely parsed.
  void HandleTranslationUnit(ASTContext &Context) {
    llvm::errs() << "********* The whole TU *************\n";
    Context.getTranslationUnitDecl()->dump();

    llvm::errs() << "****** going over the decls stored in it:\n";
    for (auto *D : Context.getTranslationUnitDecl()->decls()) {
      llvm::errs() << "Decl in the TU:\n";
      D->dump();
      llvm::errs() << "Its start location is: '"
                   << D->getLocStart().printToString(Context.getSourceManager())
                   << "'\n";
    }
  }
Пример #13
0
    virtual void HandleTopLevelDecl(DeclGroupRef D) {
      PrettyStackTraceDecl CrashInfo(*D.begin(), SourceLocation(),
                                     Context->getSourceManager(),
                                     "LLVM IR generation of declaration");

      if (llvm::TimePassesIsEnabled)
        LLVMIRGeneration.startTimer();

      Gen->HandleTopLevelDecl(D);

      if (llvm::TimePassesIsEnabled)
        LLVMIRGeneration.stopTimer();
    }
void MethodMoveTransform::HandleTranslationUnit(ASTContext &C)
{
	auto movingSpec = TransformRegistry::get().config["MethodMove"].begin();
	movingClassName = movingSpec->first.as<std::string>();
	clang::SourceManager &SM = C.getSourceManager();
	clang::FileManager &FM = SM.getFileManager();
	if(FM.getFile(movingSpec->second.as<std::string>()) == SM.getFileEntryForID(SM.getMainFileID()))
	{
		llvm::errs() << "MovingClassName: " << movingClassName << "\n";
		llvm::errs() << SM.getFileEntryForID(SM.getMainFileID())->getName() << "\n";
		auto TUD = C.getTranslationUnitDecl();
		processDeclContext(TUD);
	}
}
Пример #15
0
void CommentToXMLConverter::convertCommentToXML(const FullComment *FC,
                                                SmallVectorImpl<char> &XML,
                                                const ASTContext &Context) {
  if (!FormatContext || (FormatInMemoryUniqueId % 1000) == 0) {
    // Create a new format context, or re-create it after some number of
    // iterations, so the buffers don't grow too large.
    FormatContext.reset(new SimpleFormatContext(Context.getLangOpts()));
  }

  CommentASTToXMLConverter Converter(FC, XML, Context.getCommentCommandTraits(),
                                     Context.getSourceManager(), *FormatContext,
                                     FormatInMemoryUniqueId++);
  Converter.visit(FC);
}
SourceRange StackAddrEscapeChecker::genName(raw_ostream &os, const MemRegion *R,
                                            ASTContext &Ctx) {
    // Get the base region, stripping away fields and elements.
  R = R->getBaseRegion();
  SourceManager &SM = Ctx.getSourceManager();
  SourceRange range;
  os << "Address of ";
  
  // Check if the region is a compound literal.
  if (const CompoundLiteralRegion* CR = dyn_cast<CompoundLiteralRegion>(R)) { 
    const CompoundLiteralExpr *CL = CR->getLiteralExpr();
    os << "stack memory associated with a compound literal "
          "declared on line "
        << SM.getExpansionLineNumber(CL->getLocStart())
        << " returned to caller";    
    range = CL->getSourceRange();
  }
  else if (const AllocaRegion* AR = dyn_cast<AllocaRegion>(R)) {
    const Expr *ARE = AR->getExpr();
    SourceLocation L = ARE->getLocStart();
    range = ARE->getSourceRange();    
    os << "stack memory allocated by call to alloca() on line "
       << SM.getExpansionLineNumber(L);
  }
  else if (const BlockDataRegion *BR = dyn_cast<BlockDataRegion>(R)) {
    const BlockDecl *BD = BR->getCodeRegion()->getDecl();
    SourceLocation L = BD->getLocStart();
    range = BD->getSourceRange();
    os << "stack-allocated block declared on line "
       << SM.getExpansionLineNumber(L);
  }
  else if (const VarRegion *VR = dyn_cast<VarRegion>(R)) {
    os << "stack memory associated with local variable '"
       << VR->getString() << '\'';
    range = VR->getDecl()->getSourceRange();
  }
  else if (const CXXTempObjectRegion *TOR = dyn_cast<CXXTempObjectRegion>(R)) {
    QualType Ty = TOR->getValueType().getLocalUnqualifiedType();
    os << "stack memory associated with temporary object of type '";
    Ty.print(os, Ctx.getPrintingPolicy());
    os << "'";
    range = TOR->getExpr()->getSourceRange();
  }
  else {
    llvm_unreachable("Invalid region in ReturnStackAddressChecker.");
  } 
  
  return range;
}
Пример #17
0
void ObjCMigrateASTConsumer::HandleTranslationUnit(ASTContext &Ctx) {
  
  TranslationUnitDecl *TU = Ctx.getTranslationUnitDecl();
  for (DeclContext::decl_iterator D = TU->decls_begin(), DEnd = TU->decls_end();
       D != DEnd; ++D) {
    if (ObjCInterfaceDecl *CDecl = dyn_cast<ObjCInterfaceDecl>(*D))
      migrateObjCInterfaceDecl(Ctx, CDecl);
  }
  
  Rewriter rewriter(Ctx.getSourceManager(), Ctx.getLangOpts());
  RewritesReceiver Rec(rewriter);
  Editor->applyRewrites(Rec);

  for (Rewriter::buffer_iterator
        I = rewriter.buffer_begin(), E = rewriter.buffer_end(); I != E; ++I) {
    FileID FID = I->first;
    RewriteBuffer &buf = I->second;
    const FileEntry *file = Ctx.getSourceManager().getFileEntryForID(FID);
    assert(file);
    SmallString<512> newText;
    llvm::raw_svector_ostream vecOS(newText);
    buf.write(vecOS);
    vecOS.flush();
    llvm::MemoryBuffer *memBuf = llvm::MemoryBuffer::getMemBufferCopy(
                   StringRef(newText.data(), newText.size()), file->getName());
    SmallString<64> filePath(file->getName());
    FileMgr.FixupRelativePath(filePath);
    Remapper.remap(filePath.str(), memBuf);
  }

  if (IsOutputFile) {
    Remapper.flushToFile(MigrateDir, Ctx.getDiagnostics());
  } else {
    Remapper.flushToDisk(MigrateDir, Ctx.getDiagnostics());
  }
}
Пример #18
0
void CommentToXMLConverter::convertCommentToXML(const FullComment *FC,
                                                SmallVectorImpl<char> &XML,
                                                const ASTContext &Context) {
  if (!FormatContext) {
    FormatContext = new SimpleFormatContext(Context.getLangOpts());
  } else if ((FormatInMemoryUniqueId % 1000) == 0) {
    // Delete after some number of iterations, so the buffers don't grow
    // too large.
    delete FormatContext;
    FormatContext = new SimpleFormatContext(Context.getLangOpts());
  }

  CommentASTToXMLConverter Converter(FC, XML, Context.getCommentCommandTraits(),
                                     Context.getSourceManager(), *FormatContext,
                                     FormatInMemoryUniqueId++);
  Converter.visit(FC);
}
/// \brief If the member expression is operator-> (overloaded or not) on
/// IndexVar, include it as a valid usage and prune the traversal.
///
/// For example, given
/// \code
///   struct Foo { int bar(); int x; };
///   vector<Foo> v;
/// \endcode
/// the following uses will be considered convertible:
/// \code
///   for (vector<Foo>::iterator i = v.begin(), e = v.end(); i != e; ++i) {
///     int b = i->bar();
///     int k = i->x + 1;
///   }
/// \endcode
/// though
/// \code
///   for (vector<Foo>::iterator i = v.begin(), e = v.end(); i != e; ++i) {
///     int k = i.insert(1);
///   }
///   for (vector<Foo>::iterator i = v.begin(), e = v.end(); i != e; ++i) {
///     int b = e->bar();
///   }
/// \endcode
/// will not.
bool ForLoopIndexUseVisitor::TraverseMemberExpr(MemberExpr *Member) {
  const Expr *Base = Member->getBase();
  const DeclRefExpr *Obj = getDeclRef(Base);
  const Expr *ResultExpr = Member;
  QualType ExprType;
  if (const CXXOperatorCallExpr *Call =
      dyn_cast<CXXOperatorCallExpr>(Base->IgnoreParenImpCasts())) {
    // If operator->() is a MemberExpr containing a CXXOperatorCallExpr, then
    // the MemberExpr does not have the expression we want. We therefore catch
    // that instance here.
    // For example, if vector<Foo>::iterator defines operator->(), then the
    // example `i->bar()` at the top of this function is a CXXMemberCallExpr
    // referring to `i->` as the member function called. We want just `i`, so
    // we take the argument to operator->() as the base object.
    if(Call->getOperator() == OO_Arrow) {
      assert(Call->getNumArgs() == 1 &&
             "Operator-> takes more than one argument");
      Obj = getDeclRef(Call->getArg(0));
      ResultExpr = Obj;
      ExprType = Call->getCallReturnType();
    }
  }

  if (Member->isArrow() && Obj && exprReferencesVariable(IndexVar, Obj)) {
    if (ExprType.isNull())
      ExprType = Obj->getType();

    assert(ExprType->isPointerType() && "Operator-> returned non-pointer type");
    // FIXME: This works around not having the location of the arrow operator.
    // Consider adding OperatorLoc to MemberExpr?
    SourceLocation ArrowLoc =
        Lexer::getLocForEndOfToken(Base->getExprLoc(), 0,
                                   Context->getSourceManager(),
                                   Context->getLangOpts());
    // If something complicated is happening (i.e. the next token isn't an
    // arrow), give up on making this work.
    if (!ArrowLoc.isInvalid()) {
      Usages.push_back(Usage(ResultExpr, /*IsArrow=*/true,
                             SourceRange(Base->getExprLoc(), ArrowLoc)));
      return true;
    }
  }
  return TraverseStmt(Member->getBase());
}
Пример #20
0
static void printSourceRange(CharSourceRange range, ASTContext &Ctx,
                             raw_ostream &OS) {
  SourceManager &SM = Ctx.getSourceManager();
  const LangOptions &langOpts = Ctx.getLangOpts();

  PresumedLoc PL = SM.getPresumedLoc(range.getBegin());

  OS << llvm::sys::path::filename(PL.getFilename());
  OS << " [" << PL.getLine() << ":"
             << PL.getColumn();
  OS << " - ";

  SourceLocation end = range.getEnd();
  PL = SM.getPresumedLoc(end);

  unsigned endCol = PL.getColumn() - 1;
  if (!range.isTokenRange())
    endCol += Lexer::MeasureTokenLength(end, SM, langOpts);
  OS << PL.getLine() << ":" << endCol << "]";
}
void UnnecessaryValueParamCheck::handleMoveFix(const ParmVarDecl &Var,
                                               const DeclRefExpr &CopyArgument,
                                               const ASTContext &Context) {
  auto Diag = diag(CopyArgument.getLocStart(),
                   "parameter %0 is passed by value and only copied once; "
                   "consider moving it to avoid unnecessary copies")
              << &Var;
  // Do not propose fixes in macros since we cannot place them correctly.
  if (CopyArgument.getLocStart().isMacroID())
    return;
  const auto &SM = Context.getSourceManager();
  auto EndLoc = Lexer::getLocForEndOfToken(CopyArgument.getLocation(), 0, SM,
                                           Context.getLangOpts());
  Diag << FixItHint::CreateInsertion(CopyArgument.getLocStart(), "std::move(")
       << FixItHint::CreateInsertion(EndLoc, ")");
  if (auto IncludeFixit = Inserter->CreateIncludeInsertion(
          SM.getFileID(CopyArgument.getLocStart()), "utility",
          /*IsAngled=*/true))
    Diag << *IncludeFixit;
}
static bool isEmptyARCMTMacroStatement(NullStmt *S,
                                       std::vector<SourceLocation> &MacroLocs,
                                       ASTContext &Ctx) {
  if (!S->hasLeadingEmptyMacro())
    return false;

  SourceLocation SemiLoc = S->getSemiLoc();
  if (SemiLoc.isInvalid() || SemiLoc.isMacroID())
    return false;

  if (MacroLocs.empty())
    return false;

  SourceManager &SM = Ctx.getSourceManager();
  std::vector<SourceLocation>::iterator
    I = std::upper_bound(MacroLocs.begin(), MacroLocs.end(), SemiLoc,
                         BeforeThanCompare<SourceLocation>(SM));
  --I;
  SourceLocation
      AfterMacroLoc = I->getLocWithOffset(getARCMTMacroName().size());
  assert(AfterMacroLoc.isFileID());

  if (AfterMacroLoc == SemiLoc)
    return true;

  int RelOffs = 0;
  if (!SM.isInSameSLocAddrSpace(AfterMacroLoc, SemiLoc, &RelOffs))
    return false;
  if (RelOffs < 0)
    return false;

  // We make the reasonable assumption that a semicolon after 100 characters
  // means that it is not the next token after our macro. If this assumption
  // fails it is not critical, we will just fail to clear out, e.g., an empty
  // 'if'.
  if (RelOffs - getARCMTMacroName().size() > 100)
    return false;

  SourceLocation AfterMacroSemiLoc = findSemiAfterLocation(AfterMacroLoc, Ctx);
  return AfterMacroSemiLoc == SemiLoc;
}
Пример #23
0
	string HtDesign::getSourceLine(ASTContext &Context, SourceLocation Loc)
	{
		SourceManager & SM = Context.getSourceManager();

		// Decompose the location into a FID/Offset pair.
		std::pair<FileID, unsigned> LocInfo = SM.getDecomposedLoc(Loc);
		FileID FID = LocInfo.first;
		unsigned FileOffset = LocInfo.second;

		// Get information about the buffer it points into.
		bool Invalid = false;
		const char *BufStart = SM.getBufferData(FID, &Invalid).data();
		//if (Invalid)
		//return;

		unsigned LineNo = SM.getLineNumber(FID, FileOffset);
		unsigned ColNo = SM.getColumnNumber(FID, FileOffset);
  
		// Arbitrarily stop showing snippets when the line is too long.
		//static const size_t MaxLineLengthToPrint = 4096;
		//if (ColNo > MaxLineLengthToPrint)
		//return;

		// Rewind from the current position to the start of the line.
		const char *TokPtr = BufStart+FileOffset;
		const char *LineStart = TokPtr-ColNo+1; // Column # is 1-based.

		// Compute the line end.  Scan forward from the error position to the end of
		// the line.
		const char *LineEnd = TokPtr;
		while (*LineEnd != '\n' && *LineEnd != '\r' && *LineEnd != '\0')
		++LineEnd;

		// Arbitrarily stop showing snippets when the line is too long.
		//if (size_t(LineEnd - LineStart) > MaxLineLengthToPrint)
		//return;

		// Copy the line of code into an std::string for ease of manipulation.
		return string(LineStart, LineEnd);
	}
Пример #24
0
    bool HandleTopLevelDecl(DeclGroupRef D) override {
      PrettyStackTraceDecl CrashInfo(*D.begin(), SourceLocation(),
                                     Context->getSourceManager(),
                                     "LLVM IR generation of declaration");

      // Recurse.
      if (llvm::TimePassesIsEnabled) {
        LLVMIRGenerationRefCount += 1;
        if (LLVMIRGenerationRefCount == 1)
          LLVMIRGeneration.startTimer();
      }

      Gen->HandleTopLevelDecl(D);

      if (llvm::TimePassesIsEnabled) {
        LLVMIRGenerationRefCount -= 1;
        if (LLVMIRGenerationRefCount == 0)
          LLVMIRGeneration.stopTimer();
      }

      return true;
    }
  void HandleTranslationUnit(ASTContext &Context) override {
    const auto &SourceMgr = Context.getSourceManager();
    // The file we look for the USR in will always be the main source file.
    const auto Point = SourceMgr.getLocForStartOfFile(
        SourceMgr.getMainFileID()).getLocWithOffset(SymbolOffset);
    if (!Point.isValid())
      return;
    const NamedDecl *FoundDecl = nullptr;
    if (OldName.empty()) {
      FoundDecl = getNamedDeclAt(Context, Point);
    } else {
      FoundDecl = getNamedDeclFor(Context, OldName);
    }
    if (FoundDecl == nullptr) {
      FullSourceLoc FullLoc(Point, SourceMgr);
      errs() << "clang-rename: could not find symbol at "
             << SourceMgr.getFilename(Point) << ":"
             << FullLoc.getSpellingLineNumber() << ":"
             << FullLoc.getSpellingColumnNumber() << " (offset " << SymbolOffset
             << ").\n";
      return;
    }

    // If the decl is a constructor or destructor, we want to instead take the
    // decl of the parent record.
    if (const auto *CtorDecl = dyn_cast<CXXConstructorDecl>(FoundDecl))
      FoundDecl = CtorDecl->getParent();
    else if (const auto *DtorDecl = dyn_cast<CXXDestructorDecl>(FoundDecl))
      FoundDecl = DtorDecl->getParent();

    // If the decl is in any way relatedpp to a class, we want to make sure we
    // search for the constructor and destructor as well as everything else.
    if (const auto *Record = dyn_cast<CXXRecordDecl>(FoundDecl))
      *USRs = getAllConstructorUSRs(Record);

    USRs->push_back(getUSRForDecl(FoundDecl));
    *SpellingName = FoundDecl->getNameAsString();
  }
Пример #26
0
 virtual bool VisitObjCMessageExpr(ObjCMessageExpr *E) {
   if (E->getReceiverKind() == ObjCMessageExpr::Class) {
     QualType ReceiverType = E->getClassReceiver();
     Selector Sel = E->getSelector();
     string TypeName = ReceiverType.getAsString();
     string SelName = Sel.getAsString();
     if (TypeName == "Observer" && SelName == "observerWithTarget:action:") {
       Expr *Receiver = E->getArg(0)->IgnoreParenCasts();
       ObjCSelectorExpr* SelExpr = cast<ObjCSelectorExpr>(E->getArg(1)->IgnoreParenCasts());
       Selector Sel = SelExpr->getSelector();
       if (const ObjCObjectPointerType *OT = Receiver->getType()->getAs<ObjCObjectPointerType>()) {
         ObjCInterfaceDecl *decl = OT->getInterfaceDecl();
         if (! decl->lookupInstanceMethod(Sel)) {
           errs() << "Warning: class " << TypeName << " does not implement selector " << Sel.getAsString() << "\n";
           SourceLocation Loc = E->getExprLoc();
           PresumedLoc PLoc = astContext->getSourceManager().getPresumedLoc(Loc);
           errs() << "in " << PLoc.getFilename() << " <" << PLoc.getLine() << ":" << PLoc.getColumn() << ">\n";
         }
       }
     }
   }
   return true;
 }
Пример #27
0
/// \brief \arg Loc is the end of a statement range. This returns the location
/// of the semicolon following the statement.
/// If no semicolon is found or the location is inside a macro, the returned
/// source location will be invalid.
SourceLocation trans::findSemiAfterLocation(SourceLocation loc,
                                            ASTContext &Ctx,
                                            bool IsDecl) {
  SourceManager &SM = Ctx.getSourceManager();
  if (loc.isMacroID()) {
    if (!Lexer::isAtEndOfMacroExpansion(loc, SM, Ctx.getLangOpts(), &loc))
      return SourceLocation();
  }
  loc = Lexer::getLocForEndOfToken(loc, /*Offset=*/0, SM, Ctx.getLangOpts());

  // Break down the source location.
  std::pair<FileID, unsigned> locInfo = SM.getDecomposedLoc(loc);

  // Try to load the file buffer.
  bool invalidTemp = false;
  StringRef file = SM.getBufferData(locInfo.first, &invalidTemp);
  if (invalidTemp)
    return SourceLocation();

  const char *tokenBegin = file.data() + locInfo.second;

  // Lex from the start of the given location.
  Lexer lexer(SM.getLocForStartOfFile(locInfo.first),
              Ctx.getLangOpts(),
              file.begin(), tokenBegin, file.end());
  Token tok;
  lexer.LexFromRawLexer(tok);
  if (tok.isNot(tok::semi)) {
    if (!IsDecl)
      return SourceLocation();
    // Declaration may be followed with other tokens; such as an __attribute,
    // before ending with a semicolon.
    return findSemiAfterLocation(tok.getLocation(), Ctx, /*IsDecl*/true);
  }

  return tok.getLocation();
}
  void HandleTranslationUnit(ASTContext &Context) override {
    const SourceManager &SourceMgr = Context.getSourceManager();
    // The file we look for the USR in will always be the main source file.
    const SourceLocation Point =
        SourceMgr.getLocForStartOfFile(SourceMgr.getMainFileID())
            .getLocWithOffset(SymbolOffset);
    if (!Point.isValid())
      return;
    const NamedDecl *FoundDecl = nullptr;
    if (OldName.empty()) {
      FoundDecl = getNamedDeclAt(Context, Point);
    } else {
      FoundDecl = getNamedDeclFor(Context, OldName);
    }
    if (FoundDecl == nullptr) {
      FullSourceLoc FullLoc(Point, SourceMgr);
      errs() << "clang-rename: could not find symbol at "
             << SourceMgr.getFilename(Point) << ":"
             << FullLoc.getSpellingLineNumber() << ":"
             << FullLoc.getSpellingColumnNumber() << " (offset " << SymbolOffset
             << ").\n";
      return;
    }

    // If FoundDecl is a constructor or destructor, we want to instead take the
    // Decl of the corresponding class.
    if (const auto *CtorDecl = dyn_cast<CXXConstructorDecl>(FoundDecl)) {
      FoundDecl = CtorDecl->getParent();
    } else if (const auto *DtorDecl = dyn_cast<CXXDestructorDecl>(FoundDecl)) {
      FoundDecl = DtorDecl->getParent();
    }
    *SpellingName = FoundDecl->getNameAsString();

    AdditionalUSRFinder Finder(FoundDecl, Context, USRs);
    Finder.Find();
  }
Пример #29
0
bool SynthesizeRemovalConsumer::shouldIgnore(SourceLocation L) {
  if (!L.isValid()) {
    return true;
  }

  SourceManager &SM = astContext->getSourceManager();
  FullSourceLoc FSL(L, SM);
  const FileEntry *FE = SM.getFileEntryForID(FSL.getFileID());
  if (!FE) {
    // attempt to get the spelling location
    auto SL = SM.getSpellingLoc(L);
    if (!SL.isValid()) {
      return true;
    }
    
    FullSourceLoc FSL2(SL, SM);
    FE = SM.getFileEntryForID(FSL2.getFileID());
    if (!FE) {
      return true;
    }
  }

  return false;
}
Пример #30
0
   bool TraverseStmt(Stmt *x)
   {
		std::string classname_logendl = "logendl";

//		int id = ++_count;
//		outs() << "BEGIN TraverseStmt [" << id << "]\n";
		bool found_interesting_statement_in_this_recursion = false;
	   bool found_first_lessless_of_ilogline = false;
      if (x != nullptr)
      {
//	      auto stmt_class_name = x->getStmtClassName();
//			outs() << "  Stmt ClassName='" << stmt_class_name << "'\n";

			// Try to figure out if it's an expression we can determine a type for
	      Expr* expr = nullptr;
			switch( x->getStmtClass() )
			{
				case Stmt::CXXOperatorCallExprClass:
					{
						_output_enabled = true;
						found_interesting_statement_in_this_recursion = true;
						//outs() << "   Found Expr of interest!\n";

						CXXOperatorCallExpr* cxxoper_expr = reinterpret_cast<CXXOperatorCallExpr*>(x);
						expr = cxxoper_expr;
						if( cxxoper_expr)
						{
							//outs() << "   QualType as string: " << get_qual_type_string(cxxoper_expr) << "\n";
							if( isLessLessOfILogLine( cxxoper_expr ) )
							{
								if( !_found_logging )
								{
									found_first_lessless_of_ilogline = true;
									_found_logging = true;
									//outs() << "    Found logging!\n";
								}

                        if (found_first_lessless_of_ilogline && isLessLessOnLogEndl(cxxoper_expr))
                        {
                           _found_endl_at_end = true;
									//outs() << "      Found endl at end!\n";
                        }
                     }
						}
               }
					break;
				default:
					break;
			}
      }

		//outs() << "DIVE  TraverseStmt [" << id << "]\n";
		++_depth;
      RecursiveASTVisitor<FindNamedClassVisitor>::TraverseStmt(x);
      --_depth;
		//outs() << "END   TraverseStmt [" << id << "]\n";

		if( found_interesting_statement_in_this_recursion )
		{
			if( _found_logging && !_found_endl_at_end )
			{
				/*
				if( outs().has_colors() )
				{
				outs().changeColor(raw_ostream::RED);
				}
				*/

				FullSourceLoc FullLocation = Context->getFullLoc(x->getLocStart());
				SourceManager& SourceMgr = Context->getSourceManager();
				PresumedLoc pLoc = SourceMgr.getPresumedLoc( FullLocation );
            outs() << "ERROR on " << pLoc.getFilename() << " " << pLoc.getLine() << ":" << pLoc.getColumn()
                   << ": Found statement in which the logger is used, but endl isn't at the end\n";

            /*
				if( outs().has_colors() )
				{
				outs().changeColor(raw_ostream::WHITE, false);
				}
				*/
			}

			reset_after_recusion_into_interesting();
		}

      return true;
   }