예제 #1
0
CXCursor cxcursor::MakeCXCursor(const Decl *D, CXTranslationUnit TU,
                                SourceRange RegionOfInterest,
                                bool FirstInDeclGroup) {
  assert(D && TU && "Invalid arguments!");

  CXCursorKind K = getCursorKindForDecl(D);

  if (K == CXCursor_ObjCClassMethodDecl ||
      K == CXCursor_ObjCInstanceMethodDecl) {
    int SelectorIdIndex = -1;
    // Check if cursor points to a selector id.
    if (RegionOfInterest.isValid() &&
        RegionOfInterest.getBegin() == RegionOfInterest.getEnd()) {
      SmallVector<SourceLocation, 16> SelLocs;
      cast<ObjCMethodDecl>(D)->getSelectorLocs(SelLocs);
      SmallVectorImpl<SourceLocation>::iterator
        I=std::find(SelLocs.begin(), SelLocs.end(),RegionOfInterest.getBegin());
      if (I != SelLocs.end())
        SelectorIdIndex = I - SelLocs.begin();
    }
    CXCursor C = { K, SelectorIdIndex,
                   { D, (void*)(intptr_t) (FirstInDeclGroup ? 1 : 0), TU }};
    return C;
  }
  
  CXCursor C = { K, 0, { D, (void*)(intptr_t) (FirstInDeclGroup ? 1 : 0), TU }};
  return C;
}
예제 #2
0
void RemoveUnusedStructField::removeOneInitExpr(const Expr *E)
{
  TransAssert(NumFields && "NumFields cannot be zero!");

  SourceRange ExpRange = E->getSourceRange();
  SourceLocation StartLoc = ExpRange.getBegin();
  SourceLocation EndLoc = ExpRange.getEnd();

  if (NumFields == 1) {
    // The last field can optionally have a trailing comma
    // If this is the only field also the comma has to be removed
    SourceLocation NewEndLoc =
      RewriteHelper->getEndLocationUntil(ExpRange, '}');
    NewEndLoc = NewEndLoc.getLocWithOffset(-1);

    TheRewriter.RemoveText(SourceRange(StartLoc, NewEndLoc));

    return;
  }
  else if (IsFirstField) {
    EndLoc = RewriteHelper->getEndLocationUntil(ExpRange, ',');
    TheRewriter.RemoveText(SourceRange(StartLoc, EndLoc));
    return;
  }

  const char *Buf = SrcManager->getCharacterData(StartLoc);
  int Offset = 0;
  while (*Buf != ',') {
    Buf--;
    Offset--;
  }
  StartLoc = StartLoc.getLocWithOffset(Offset);
  TheRewriter.RemoveText(SourceRange(StartLoc, EndLoc));
}
static void addUsage(IdentifierNamingCheck::NamingCheckFailureMap &Failures,
                     const IdentifierNamingCheck::NamingCheckId &Decl,
                     SourceRange Range, SourceManager *SourceMgr = nullptr) {
  // Do nothing if the provided range is invalid.
  if (Range.getBegin().isInvalid() || Range.getEnd().isInvalid())
    return;

  // If we have a source manager, use it to convert to the spelling location for
  // performing the fix. This is necessary because macros can map the same
  // spelling location to different source locations, and we only want to fix
  // the token once, before it is expanded by the macro.
  SourceLocation FixLocation = Range.getBegin();
  if (SourceMgr)
    FixLocation = SourceMgr->getSpellingLoc(FixLocation);
  if (FixLocation.isInvalid())
    return;

  // Try to insert the identifier location in the Usages map, and bail out if it
  // is already in there
  auto &Failure = Failures[Decl];
  if (!Failure.RawUsageLocs.insert(FixLocation.getRawEncoding()).second)
    return;

  if (!Failure.ShouldFix)
    return;

  // Check if the range is entirely contained within a macro argument.
  SourceLocation MacroArgExpansionStartForRangeBegin;
  SourceLocation MacroArgExpansionStartForRangeEnd;
  bool RangeIsEntirelyWithinMacroArgument =
      SourceMgr &&
      SourceMgr->isMacroArgExpansion(Range.getBegin(),
                                     &MacroArgExpansionStartForRangeBegin) &&
      SourceMgr->isMacroArgExpansion(Range.getEnd(),
                                     &MacroArgExpansionStartForRangeEnd) &&
      MacroArgExpansionStartForRangeBegin == MacroArgExpansionStartForRangeEnd;

  // Check if the range contains any locations from a macro expansion.
  bool RangeContainsMacroExpansion = RangeIsEntirelyWithinMacroArgument ||
                                     Range.getBegin().isMacroID() ||
                                     Range.getEnd().isMacroID();

  bool RangeCanBeFixed =
      RangeIsEntirelyWithinMacroArgument || !RangeContainsMacroExpansion;
  Failure.ShouldFix = RangeCanBeFixed;
}
예제 #4
0
CXCursor cxcursor::MakePreprocessingDirectiveCursor(SourceRange Range, 
                                                    CXTranslationUnit TU) {
  CXCursor C = { CXCursor_PreprocessingDirective, 
                 { reinterpret_cast<void *>(Range.getBegin().getRawEncoding()),
                   reinterpret_cast<void *>(Range.getEnd().getRawEncoding()),
                   TU }
               };
  return C;
}
예제 #5
0
파일: CXCursor.cpp 프로젝트: martong/clang
CXCursor cxcursor::MakePreprocessingDirectiveCursor(SourceRange Range, 
                                                    CXTranslationUnit TU) {
  CXCursor C = { CXCursor_PreprocessingDirective, 0,
                 { Range.getBegin().getPtrEncoding(),
                   Range.getEnd().getPtrEncoding(),
                   TU }
               };
  return C;
}
예제 #6
0
static Optional<bool> comparePiece(const PathDiagnosticPiece &X,
                                   const PathDiagnosticPiece &Y) {
  if (X.getKind() != Y.getKind())
    return X.getKind() < Y.getKind();

  FullSourceLoc XL = X.getLocation().asLocation();
  FullSourceLoc YL = Y.getLocation().asLocation();
  if (XL != YL)
    return XL.isBeforeInTranslationUnitThan(YL);

  if (X.getString() != Y.getString())
    return X.getString() < Y.getString();

  if (X.getRanges().size() != Y.getRanges().size())
    return X.getRanges().size() < Y.getRanges().size();

  const SourceManager &SM = XL.getManager();

  for (unsigned i = 0, n = X.getRanges().size(); i < n; ++i) {
    SourceRange XR = X.getRanges()[i];
    SourceRange YR = Y.getRanges()[i];
    if (XR != YR) {
      if (XR.getBegin() != YR.getBegin())
        return SM.isBeforeInTranslationUnit(XR.getBegin(), YR.getBegin());
      return SM.isBeforeInTranslationUnit(XR.getEnd(), YR.getEnd());
    }
  }

  switch (X.getKind()) {
    case PathDiagnosticPiece::ControlFlow:
      return compareControlFlow(cast<PathDiagnosticControlFlowPiece>(X),
                                cast<PathDiagnosticControlFlowPiece>(Y));
    case PathDiagnosticPiece::Event:
    case PathDiagnosticPiece::Note:
      return None;
    case PathDiagnosticPiece::Macro:
      return compareMacro(cast<PathDiagnosticMacroPiece>(X),
                          cast<PathDiagnosticMacroPiece>(Y));
    case PathDiagnosticPiece::Call:
      return compareCall(cast<PathDiagnosticCallPiece>(X),
                         cast<PathDiagnosticCallPiece>(Y));
  }
  llvm_unreachable("all cases handled");
}
예제 #7
0
    int getNumberOfLines(SourceRange sourceRange)
    {
        SourceLocation startLocation = sourceRange.getBegin();
        SourceLocation endLocation = sourceRange.getEnd();
        SourceManager *sourceManager = &_carrier->astContext()->getSourceManager();

        unsigned startLineNumber = sourceManager->getPresumedLineNumber(startLocation);
        unsigned endLineNumber = sourceManager->getPresumedLineNumber(endLocation);
        return endLineNumber - startLineNumber + 1;
    }
예제 #8
0
void StmtDumper::DumpSourceRange(const Stmt *Node) {
  // Can't translate locations if a SourceManager isn't available.
  if (SM == 0) return;

  // TODO: If the parent expression is available, we can print a delta vs its
  // location.
  SourceRange R = Node->getSourceRange();

  OS << " <";
  DumpLocation(R.getBegin());
  if (R.getBegin() != R.getEnd()) {
    OS << ", ";
    DumpLocation(R.getEnd());
  }
  OS << ">";

  // <t2.c:123:421[blah], t2.c:412:321>

}
/// \brief Obtain the original source code text from a SourceRange.
static StringRef getStringFromRange(SourceManager &SourceMgr,
                                    const LangOptions &LangOpts,
                                    SourceRange Range) {
  if (SourceMgr.getFileID(Range.getBegin()) !=
      SourceMgr.getFileID(Range.getEnd()))
    return NULL;

  CharSourceRange SourceChars(Range, true);
  return Lexer::getSourceText(SourceChars, SourceMgr, LangOpts);
}
예제 #10
0
void ForStmt::setConditionVariable(ASTContext &C, VarDecl *V) {
  if (!V) {
    SubExprs[CONDVAR] = 0;
    return;
  }

  SourceRange VarRange = V->getSourceRange();
  SubExprs[CONDVAR] = new (C) DeclStmt(DeclGroupRef(V), VarRange.getBegin(),
                                       VarRange.getEnd());
}
예제 #11
0
std::string SynthesizeRemovalConsumer::range(SourceRange R) {
  std::string src;
  llvm::raw_string_ostream sst(src);
  sst << "(";
  R.getBegin().print(sst, astContext->getSourceManager());
  sst << ", ";
  R.getEnd().print(sst, astContext->getSourceManager());
  sst << ")";
  return sst.str();
}
예제 #12
0
/// getRewrittenText - Return the rewritten form of the text in the specified
/// range.  If the start or end of the range was unrewritable or if they are
/// in different buffers, this returns an empty string.
///
/// Note that this method is not particularly efficient.
///
std::string Rewriter::getRewrittenText(SourceRange Range) const {
  if (!isRewritable(Range.getBegin()) ||
      !isRewritable(Range.getEnd()))
    return "";

  FileID StartFileID, EndFileID;
  unsigned StartOff, EndOff;
  StartOff = getLocationOffsetAndFileID(Range.getBegin(), StartFileID);
  EndOff   = getLocationOffsetAndFileID(Range.getEnd(), EndFileID);

  if (StartFileID != EndFileID)
    return ""; // Start and end in different buffers.

  // If edits have been made to this buffer, the delta between the range may
  // have changed.
  std::map<FileID, RewriteBuffer>::const_iterator I =
    RewriteBuffers.find(StartFileID);
  if (I == RewriteBuffers.end()) {
    // If the buffer hasn't been rewritten, just return the text from the input.
    const char *Ptr = SourceMgr->getCharacterData(Range.getBegin());

    // Adjust the end offset to the end of the last token, instead of being the
    // start of the last token.
    EndOff += Lexer::MeasureTokenLength(Range.getEnd(), *SourceMgr, *LangOpts);
    return std::string(Ptr, Ptr+EndOff-StartOff);
  }

  const RewriteBuffer &RB = I->second;
  EndOff = RB.getMappedOffset(EndOff, true);
  StartOff = RB.getMappedOffset(StartOff);

  // Adjust the end offset to the end of the last token, instead of being the
  // start of the last token.
  EndOff += Lexer::MeasureTokenLength(Range.getEnd(), *SourceMgr, *LangOpts);

  // Advance the iterators to the right spot, yay for linear time algorithms.
  RewriteBuffer::iterator Start = RB.begin();
  std::advance(Start, StartOff);
  RewriteBuffer::iterator End = Start;
  std::advance(End, EndOff-StartOff);

  return std::string(Start, End);
}
예제 #13
0
파일: Stmt.cpp 프로젝트: elfprince13/clang
void WhileStmt::setConditionVariable(const ASTContext &C, VarDecl *V) {
  if (!V) {
    SubExprs[VAR] = nullptr;
    return;
  }

  SourceRange VarRange = V->getSourceRange();
  SubExprs[VAR] = new (C) DeclStmt(DeclGroupRef(V), VarRange.getBegin(),
                                   VarRange.getEnd());
}
예제 #14
0
bool RewriteUtils::removeVarFromDeclStmt(DeclStmt *DS,
                                         const VarDecl *VD,
                                         Decl *PrevDecl,
                                         bool IsFirstDecl)
{
  SourceRange StmtRange = DS->getSourceRange();

  // VD is the the only declaration, so it is safe to remove the entire stmt
  if (DS->isSingleDecl()) {
    return !(TheRewriter->RemoveText(StmtRange));
  }

  // handle the case where we could have implicit declaration of RecordDecl
  // e.g., 
  // foo (void) {
  //   struct S0 *s;
  //   ...;
  // }
  // in this case, struct S0 is implicitly declared
  if (PrevDecl) {
    if ( RecordDecl *RD = dyn_cast<RecordDecl>(PrevDecl) ) {
      DeclGroup DGroup = DS->getDeclGroup().getDeclGroup();
      IsFirstDecl = true;
      if (!RD->getDefinition() && DGroup.size() == 2)
        return !(TheRewriter->RemoveText(StmtRange));
    }
  }

  SourceRange VarRange = VD->getSourceRange();

  // VD is the first declaration in a declaration group.
  // We keep the leading type string
  if (IsFirstDecl) {
    // We need to get the outermost TypeLocEnd instead of the StartLoc of
    // a var name, because we need to handle the case below:
    //   int *x, *y;
    // If we rely on the StartLoc of a var name, then we will make bad
    // transformation like:
    //   int * *y;
    SourceLocation NewStartLoc = getVarDeclTypeLocEnd(VD);

    SourceLocation NewEndLoc = getEndLocationUntil(VarRange, ',');
    
    return 
      !(TheRewriter->RemoveText(SourceRange(NewStartLoc, NewEndLoc)));
  }

  TransAssert(PrevDecl && "PrevDecl cannot be NULL!");
  SourceLocation VarEndLoc = VarRange.getEnd();
  SourceRange PrevDeclRange = PrevDecl->getSourceRange();

  SourceLocation PrevDeclEndLoc = getEndLocationUntil(PrevDeclRange, ',');

  return !(TheRewriter->RemoveText(SourceRange(PrevDeclEndLoc, VarEndLoc)));
}
예제 #15
0
void CodeGenFunction::GenerateCode(GlobalDecl GD, llvm::Function *Fn,
                                   const CGFunctionInfo &FnInfo) {
  const FunctionDecl *FD = cast<FunctionDecl>(GD.getDecl());
  
  // Check if we should generate debug info for this function.
  if (CGM.getModuleDebugInfo() && !FD->hasAttr<NoDebugAttr>())
    DebugInfo = CGM.getModuleDebugInfo();

  FunctionArgList Args;
  QualType ResTy = FD->getResultType();

  CurGD = GD;
  if (isa<CXXMethodDecl>(FD) && cast<CXXMethodDecl>(FD)->isInstance())
    CGM.getCXXABI().BuildInstanceFunctionParams(*this, ResTy, Args);

  for (unsigned i = 0, e = FD->getNumParams(); i != e; ++i)
    Args.push_back(FD->getParamDecl(i));

  SourceRange BodyRange;
  if (Stmt *Body = FD->getBody()) BodyRange = Body->getSourceRange();

  // Emit the standard function prologue.
  StartFunction(GD, ResTy, Fn, FnInfo, Args, BodyRange.getBegin());

  // Generate the body of the function.
  if (isa<CXXDestructorDecl>(FD))
    EmitDestructorBody(Args);
  else if (isa<CXXConstructorDecl>(FD))
    EmitConstructorBody(Args);
  else if (getContext().getLangOpts().CUDA &&
           !CGM.getCodeGenOpts().CUDAIsDevice &&
           FD->hasAttr<CUDAGlobalAttr>())
    CGM.getCUDARuntime().EmitDeviceStubBody(*this, Args);
  else if (isa<CXXConversionDecl>(FD) &&
           cast<CXXConversionDecl>(FD)->isLambdaToBlockPointerConversion()) {
    // The lambda conversion to block pointer is special; the semantics can't be
    // expressed in the AST, so IRGen needs to special-case it.
    EmitLambdaToBlockPointerBody(Args);
  } else if (isa<CXXMethodDecl>(FD) &&
             cast<CXXMethodDecl>(FD)->isLambdaStaticInvoker()) {
    // The lambda "__invoke" function is special, because it forwards or
    // clones the body of the function call operator (but is actually static).
    EmitLambdaStaticInvokeFunction(cast<CXXMethodDecl>(FD));
  }
  else
    EmitFunctionBody(Args);

  // Emit the standard function epilogue.
  FinishFunction(BodyRange.getEnd());

  // If we haven't marked the function nothrow through other means, do
  // a quick pass now to see if we can.
  if (!CurFn->doesNotThrow())
    TryMarkNoThrow(CurFn);
}
void WhitespaceManager::storeReplacement(const SourceRange &Range,
                                         StringRef Text) {
  unsigned WhitespaceLength = SourceMgr.getFileOffset(Range.getEnd()) -
                              SourceMgr.getFileOffset(Range.getBegin());
  // Don't create a replacement, if it does not change anything.
  if (StringRef(SourceMgr.getCharacterData(Range.getBegin()),
                WhitespaceLength) == Text)
    return;
  Replaces.insert(tooling::Replacement(
      SourceMgr, CharSourceRange::getCharRange(Range), Text));
}
예제 #17
0
bool RewriteUtils::removeVarInitExpr(const VarDecl *VD)
{
  TransAssert(VD->hasInit() && "VarDecl doesn't have an Init Expr!");
  SourceLocation NameStartLoc = VD->getLocation();

  SourceLocation InitStartLoc = getLocationUntil(NameStartLoc, '=');

  const Expr *Init = VD->getInit();
  SourceRange ExprRange = Init->getSourceRange();
  SourceLocation InitEndLoc = ExprRange.getEnd();
  return !TheRewriter->RemoveText(SourceRange(InitStartLoc, InitEndLoc));
}
예제 #18
0
파일: ARCMT.cpp 프로젝트: CTSRD-TESLA/clang
bool CapturedDiagList::hasDiagnostic(ArrayRef<unsigned> IDs,
                                     SourceRange range) const {
  if (range.isInvalid())
    return false;

  ListTy::const_iterator I = List.begin();
  while (I != List.end()) {
    FullSourceLoc diagLoc = I->getLocation();
    if ((IDs.empty() || // empty means any diagnostic in the range.
         std::find(IDs.begin(), IDs.end(), I->getID()) != IDs.end()) &&
        !diagLoc.isBeforeInTranslationUnitThan(range.getBegin()) &&
        (diagLoc == range.getEnd() ||
           diagLoc.isBeforeInTranslationUnitThan(range.getEnd()))) {
      return true;
    }

    ++I;
  }

  return false;
}
    /* We print this in a format that Python can easily understand and parse */
    void PrintFunctionInfo(const FunctionDecl *fd)
    {
        SourceRange sr = fd->getSourceRange();
        PresumedLoc begin = sm->getPresumedLoc(sr.getBegin());
        PresumedLoc end = sm->getPresumedLoc(sr.getEnd());

        std::cout << "{'function': '" << fd->getDeclName().getAsString() << "'";
        std::cout << ", 'file': '" << begin.getFilename() << "'";
        std::cout << ", 'begin': [" << begin.getLine() << ", " << begin.getColumn() << "]";
        std::cout << ", 'end': [" << end.getLine() << ", " << end.getColumn() << "]";
        std::cout << "}" << std::endl;
    }
예제 #20
0
/// HandleComment - Hook into the preprocessor and extract comments containing
///  expected errors and warnings.
bool VerifyDiagnosticConsumer::HandleComment(Preprocessor &PP,
                                             SourceRange Comment) {
  SourceManager &SM = PP.getSourceManager();

  // If this comment is for a different source manager, ignore it.
  if (SrcManager && &SM != SrcManager)
    return false;

  SourceLocation CommentBegin = Comment.getBegin();

  const char *CommentRaw = SM.getCharacterData(CommentBegin);
  StringRef C(CommentRaw, SM.getCharacterData(Comment.getEnd()) - CommentRaw);

  if (C.empty())
    return false;

  // Fold any "\<EOL>" sequences
  size_t loc = C.find('\\');
  if (loc == StringRef::npos) {
    ParseDirective(C, &ED, SM, &PP, CommentBegin, Status, *Markers);
    return false;
  }

  std::string C2;
  C2.reserve(C.size());

  for (size_t last = 0;; loc = C.find('\\', last)) {
    if (loc == StringRef::npos || loc == C.size()) {
      C2 += C.substr(last);
      break;
    }
    C2 += C.substr(last, loc-last);
    last = loc + 1;

    if (C[last] == '\n' || C[last] == '\r') {
      ++last;

      // Escape \r\n  or \n\r, but not \n\n.
      if (last < C.size())
        if (C[last] == '\n' || C[last] == '\r')
          if (C[last] != C[last-1])
            ++last;
    } else {
      // This was just a normal backslash.
      C2 += '\\';
    }
  }

  if (!C2.empty())
    ParseDirective(C2, &ED, SM, &PP, CommentBegin, Status, *Markers);
  return false;
}
예제 #21
0
bool RemoveUnusedFunction::hasAtLeastOneValidLocation(const FunctionDecl *FD)
{
  for (FunctionDecl::redecl_iterator RI = FD->redecls_begin(),
       RE = FD->redecls_end(); RI != RE; ++RI) {
    SourceRange FuncRange = FD->getSourceRange();
    SourceLocation StartLoc = FuncRange.getBegin();
    SourceLocation EndLoc = FuncRange.getEnd();
    if (SrcManager->isWrittenInMainFile(StartLoc) && 
        SrcManager->isWrittenInMainFile(EndLoc))
      return true;
  }
  return false;
}
예제 #22
0
bool Rewriter::ReplaceText(SourceRange range, SourceRange replacementRange) {
  if (!isRewritable(range.getBegin())) return true;
  if (!isRewritable(range.getEnd())) return true;
  if (replacementRange.isInvalid()) return true;
  SourceLocation start = range.getBegin();
  unsigned origLength = getRangeSize(range);
  unsigned newLength = getRangeSize(replacementRange);
  FileID FID;
  unsigned newOffs = getLocationOffsetAndFileID(replacementRange.getBegin(),
                                                FID);
  StringRef MB = SourceMgr->getBufferData(FID);
  return ReplaceText(start, origLength, MB.substr(newOffs, newLength));
}
예제 #23
0
/// HandleComment - Hook into the preprocessor and extract comments containing
///  expected errors and warnings.
bool VerifyDiagnosticConsumer::HandleComment(Preprocessor &PP,
                                             SourceRange Comment) {
  SourceManager &SM = PP.getSourceManager();
  SourceLocation CommentBegin = Comment.getBegin();

  const char *CommentRaw = SM.getCharacterData(CommentBegin);
  StringRef C(CommentRaw, SM.getCharacterData(Comment.getEnd()) - CommentRaw);

  if (C.empty())
    return false;

  // Fold any "\<EOL>" sequences
  size_t loc = C.find('\\');
  if (loc == StringRef::npos) {
    if (ParseDirective(C, ED, SM, CommentBegin, PP.getDiagnostics()))
      if (const FileEntry *E = SM.getFileEntryForID(SM.getFileID(CommentBegin)))
        FilesWithDirectives.insert(E);
    return false;
  }

  std::string C2;
  C2.reserve(C.size());

  for (size_t last = 0;; loc = C.find('\\', last)) {
    if (loc == StringRef::npos || loc == C.size()) {
      C2 += C.substr(last);
      break;
    }
    C2 += C.substr(last, loc-last);
    last = loc + 1;

    if (C[last] == '\n' || C[last] == '\r') {
      ++last;

      // Escape \r\n  or \n\r, but not \n\n.
      if (last < C.size())
        if (C[last] == '\n' || C[last] == '\r')
          if (C[last] != C[last-1])
            ++last;
    } else {
      // This was just a normal backslash.
      C2 += '\\';
    }
  }

  if (!C2.empty())
    if (ParseDirective(C2, ED, SM, CommentBegin, PP.getDiagnostics()))
      if (const FileEntry *E = SM.getFileEntryForID(SM.getFileID(CommentBegin)))
        FilesWithDirectives.insert(E);
  return false;
}
예제 #24
0
void HTMLDiagnostics::HighlightRange(Rewriter& R, FileID BugFileID,
                                     SourceRange Range,
                                     const char *HighlightStart,
                                     const char *HighlightEnd) {
  SourceManager &SM = R.getSourceMgr();
  const LangOptions &LangOpts = R.getLangOpts();

  SourceLocation InstantiationStart = SM.getExpansionLoc(Range.getBegin());
  unsigned StartLineNo = SM.getExpansionLineNumber(InstantiationStart);

  SourceLocation InstantiationEnd = SM.getExpansionLoc(Range.getEnd());
  unsigned EndLineNo = SM.getExpansionLineNumber(InstantiationEnd);

  if (EndLineNo < StartLineNo)
    return;

  if (SM.getFileID(InstantiationStart) != BugFileID ||
      SM.getFileID(InstantiationEnd) != BugFileID)
    return;

  // Compute the column number of the end.
  unsigned EndColNo = SM.getExpansionColumnNumber(InstantiationEnd);
  unsigned OldEndColNo = EndColNo;

  if (EndColNo) {
    // Add in the length of the token, so that we cover multi-char tokens.
    EndColNo += Lexer::MeasureTokenLength(Range.getEnd(), SM, LangOpts)-1;
  }

  // Highlight the range.  Make the span tag the outermost tag for the
  // selected range.

  SourceLocation E =
    InstantiationEnd.getLocWithOffset(EndColNo - OldEndColNo);

  html::HighlightRange(R, InstantiationStart, E, HighlightStart, HighlightEnd);
}
예제 #25
0
void ReturnVoid::keepFuncDefRange(FunctionDecl *FD)
{
  TransAssert(!FuncDefStartPos && !FuncDefEndPos && 
         "Duplicated function definition?");

  SourceRange FuncDefRange = FD->getSourceRange();

  SourceLocation StartLoc = FuncDefRange.getBegin();
  FuncDefStartPos = 
      SrcManager->getCharacterData(StartLoc);

  SourceLocation EndLoc = FuncDefRange.getEnd();
  FuncDefEndPos = 
      SrcManager->getCharacterData(EndLoc);
}
예제 #26
0
bool RewriteUtils::removeTextUntil(SourceRange Range, char C)
{
  SourceLocation StartLoc = Range.getBegin();

  // I don't know the reason, but seems Clang treats the following two
  // cases differently:
  // (1) template<bool, typename>
  //    in this case, the RangeSize is 5, which includes the ','
  // (2) template<typename, typename>
  //    in this case, the RangeSize is 8, which excludes the comma
  SourceLocation EndLoc = Range.getEnd();
  const char *EndBuf = SrcManager->getCharacterData(EndLoc);
  if (*EndBuf != C)
    EndLoc = getEndLocationUntil(Range, C);
  return !TheRewriter->RemoveText(SourceRange(StartLoc, EndLoc));
}
예제 #27
0
bool RewriteUtils::removeArraySubscriptExpr(const Expr *E)
{
  SourceRange ERange = E->getSourceRange();
  SourceLocation StartLoc = ERange.getBegin();
  const char *StartBuf = SrcManager->getCharacterData(StartLoc);
  int Offset = 0;
  while (*StartBuf != '[') {
    StartBuf--;
    Offset--;
  }
  StartLoc = StartLoc.getLocWithOffset(Offset);

  SourceLocation EndLoc = ERange.getEnd();
  EndLoc = getLocationUntil(EndLoc, ']');
  return !TheRewriter->RemoveText(SourceRange(StartLoc, EndLoc));
}
예제 #28
0
파일: CallTree.cpp 프로젝트: Caian/Crowbar
	int runFD(const FunctionDecl *md, SourceManager &sm)
	{
		if (!md->hasBody())
			return 0;

		if (!md->isThisDeclarationADefinition())
			return 0;

		DeclarationNameInfo info = md->getNameInfo();
		
		FullSourceLoc b(md->getLocStart(), sm), _e(md->getLocEnd(), sm);
		FullSourceLoc e(clang::Lexer::getLocForEndOfToken(_e, 0, sm, *this->lopt), sm);
		
		SourceRange nameRange = SourceRange(info.getLoc());
		FullSourceLoc d(nameRange.getBegin(), sm), _f(nameRange.getEnd(), sm);
		FullSourceLoc f(clang::Lexer::getLocForEndOfToken(_f, 0, sm, *this->lopt), sm);

		string start(sm.getCharacterData(b), sm.getCharacterData(d)-sm.getCharacterData(b));
		string name(sm.getCharacterData(d), sm.getCharacterData(f)-sm.getCharacterData(d));
		string end(sm.getCharacterData(f), sm.getCharacterData(e)-sm.getCharacterData(f));

		if (this->methods.find(name) != this->methods.end())
		{
			message("Redefinition of method " + name);
			return 1;
		}

		METHOD* m = new METHOD();
		m->pre = start;
		m->name = name;
		m->post = end;

		getAbsoluteLocation(FullSourceLoc(md->getLocStart(), sm), 
				FullSourceLoc(md->getLocEnd(), sm), 
				&m->location.begin, &m->location.end, *this->lopt);

		m->sm = &sm;
		m->range = CharSourceRange::
			getTokenRange(SourceRange(info.getLoc()));

		this->methods[name] = m;

		// For debugging purposes
		// cout << start << "|" << name << "|" << end << endl;

		return 0;
	}
예제 #29
0
    virtual void run(const MatchFinder::MatchResult &Result) {
        auto *d = Result.Nodes.getNodeAs<CXXConstructorDecl>("stuff");
        if (d) {
            if (d->getNumCtorInitializers() > 0) {
                const CXXCtorInitializer *firstinit = *d->init_begin();
                if (!firstinit->isWritten()) {
                    llvm::errs() << "firstinit not written; skipping\n";
                    return;
                }
                if (firstinit->isBaseInitializer()) {
                    TypeLoc basetypeloc = firstinit->getBaseClassLoc();
                    llvm::errs() << "firstinit as base loc: "
                                 << basetypeloc.getBeginLoc().printToString(
                                     *Result.SourceManager) << "\n";
                }
                SourceLocation initloc = firstinit->getSourceLocation();
                llvm::errs() << "firstinit loc: "
                             << initloc.printToString(*Result.SourceManager) << "\n";
                SourceRange initrange = firstinit->getSourceRange();
                llvm::errs() << "firstinit range from "
                             << initrange.getBegin().printToString(
                                 *Result.SourceManager) << "\n";
                llvm::errs() << "firstinit range to "
                             << initrange.getEnd().printToString(
                                 *Result.SourceManager) << "\n";

                SourceLocation start = firstinit->getLParenLoc();
                llvm::errs() << "firstinit start: "
                             << start.printToString(*Result.SourceManager) << "\n";
                Token tok_id = GetTokenBeforeLocation(start, *Result.Context);
                llvm::errs() << "  tok_id: "
                             << tok_id.getLocation().printToString(
                                 *Result.SourceManager) << "\n";
                Token tok_colon =
                    GetTokenBeforeLocation(tok_id.getLocation(), *Result.Context);
                llvm::errs() << "  tok_colon: "
                             << tok_colon.getLocation().printToString(
                                 *Result.SourceManager) << "\n";

                const CXXCtorInitializer *lastinit = *d->init_rbegin();
                SourceLocation end = lastinit->getRParenLoc();
                llvm::errs() << "lastinit end: "
                             << end.printToString(*Result.SourceManager) << "\n";
                //init->getInit()->dump();
            }
        }
    }
void ReturnBracedInitListCheck::check(const MatchFinder::MatchResult &Result) {
  const auto *MatchedFunctionDecl = Result.Nodes.getNodeAs<FunctionDecl>("fn");
  const auto *MatchedConstructExpr =
      Result.Nodes.getNodeAs<CXXConstructExpr>("ctor");

  // Don't make replacements in macro.
  SourceLocation Loc = MatchedConstructExpr->getExprLoc();
  if (Loc.isMacroID())
    return;

  // Make sure that the return type matches the constructed type.
  const QualType ReturnType =
      MatchedFunctionDecl->getReturnType().getCanonicalType();
  const QualType ConstructType =
      MatchedConstructExpr->getType().getCanonicalType();
  if (ReturnType != ConstructType)
    return;

  auto Diag = diag(Loc, "avoid repeating the return type from the "
                        "declaration; use a braced initializer list instead");

  const SourceRange CallParensRange =
      MatchedConstructExpr->getParenOrBraceRange();

  // Make sure there is an explicit constructor call.
  if (CallParensRange.isInvalid())
    return;

  // Make sure that the ctor arguments match the declaration.
  for (unsigned I = 0, NumParams = MatchedConstructExpr->getNumArgs();
       I < NumParams; ++I) {
    if (const auto *VD = dyn_cast<VarDecl>(
            MatchedConstructExpr->getConstructor()->getParamDecl(I))) {
      if (MatchedConstructExpr->getArg(I)->getType().getCanonicalType() !=
          VD->getType().getCanonicalType())
        return;
    }
  }

  // Range for constructor name and opening brace.
  CharSourceRange CtorCallSourceRange = CharSourceRange::getTokenRange(
      Loc, CallParensRange.getBegin().getLocWithOffset(-1));

  Diag << FixItHint::CreateRemoval(CtorCallSourceRange)
       << FixItHint::CreateReplacement(CallParensRange.getBegin(), "{")
       << FixItHint::CreateReplacement(CallParensRange.getEnd(), "}");
}