//---------------------------------------------------------
void DocumentXML::addLocationRange(const SourceRange& R)
{
  PresumedLoc PStartLoc = addLocation(R.getBegin());
  if (R.getBegin() != R.getEnd())
  {
    SourceManager& SM = Ctx->getSourceManager();
    SourceLocation SpellingLoc = SM.getSpellingLoc(R.getEnd());
    if (!SpellingLoc.isInvalid())
    {
      PresumedLoc PLoc = SM.getPresumedLoc(SpellingLoc);
      if (PStartLoc.isInvalid() ||
          strcmp(PLoc.getFilename(), PStartLoc.getFilename()) != 0) {
        addToMap(SourceFiles, PLoc.getFilename(), ID_FILE);
        addAttribute("endfile", PLoc.getFilename());
        addAttribute("endline", PLoc.getLine());
        addAttribute("endcol", PLoc.getColumn());
      } else if (PLoc.getLine() != PStartLoc.getLine()) {
        addAttribute("endline", PLoc.getLine());
        addAttribute("endcol", PLoc.getColumn());
      } else {
        addAttribute("endcol", PLoc.getColumn());
      }
    }
  }
}
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));
}
std::pair<unsigned, unsigned>
PreprocessingRecord::findLocalPreprocessedEntitiesInRange(
                                                      SourceRange Range) const {
  if (Range.isInvalid())
    return std::make_pair(0,0);
  assert(!SourceMgr.isBeforeInTranslationUnit(Range.getEnd(),Range.getBegin()));

  unsigned Begin = findBeginLocalPreprocessedEntity(Range.getBegin());
  unsigned End = findEndLocalPreprocessedEntity(Range.getEnd());
  return std::make_pair(Begin, End);
}
예제 #4
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));
}
예제 #5
0
/// HighlightRange - Given a SourceRange and a line number, highlight (with ~'s)
/// any characters in LineNo that intersect the SourceRange.
void TextDiagnosticPrinter::HighlightRange(const SourceRange &R,
                                          SourceManager& SourceMgr,
                                           unsigned LineNo,
                                           std::string &CaratLine,
                                           const std::string &SourceLine) {  
  assert(CaratLine.size() == SourceLine.size() &&
         "Expect a correspondence between source and carat line!");
  if (!R.isValid()) return;

  unsigned StartLineNo = SourceMgr.getLogicalLineNumber(R.getBegin());
  if (StartLineNo > LineNo) return;  // No intersection.
  
  unsigned EndLineNo = SourceMgr.getLogicalLineNumber(R.getEnd());
  if (EndLineNo < LineNo) return;  // No intersection.
  
  // Compute the column number of the start.
  unsigned StartColNo = 0;
  if (StartLineNo == LineNo) {
    StartColNo = SourceMgr.getLogicalColumnNumber(R.getBegin());
    if (StartColNo) --StartColNo;  // Zero base the col #.
  }

  // Pick the first non-whitespace column.
  while (StartColNo < SourceLine.size() &&
         (SourceLine[StartColNo] == ' ' || SourceLine[StartColNo] == '\t'))
    ++StartColNo;
  
  // Compute the column number of the end.
  unsigned EndColNo = CaratLine.size();
  if (EndLineNo == LineNo) {
    EndColNo = SourceMgr.getLogicalColumnNumber(R.getEnd());
    if (EndColNo) {
      --EndColNo;  // Zero base the col #.
      
      // Add in the length of the token, so that we cover multi-char tokens.
      EndColNo += Lexer::MeasureTokenLength(R.getEnd(), SourceMgr);
    } else {
      EndColNo = CaratLine.size();
    }
  }
  
  // Pick the last non-whitespace column.
  while (EndColNo-1 &&
         (SourceLine[EndColNo-1] == ' ' || SourceLine[EndColNo-1] == '\t'))
    --EndColNo;
  
  // Fill the range with ~'s.
  assert(StartColNo <= EndColNo && "Invalid range!");
  for (unsigned i = StartColNo; i != EndColNo; ++i)
    CaratLine[i] = '~';
}
예제 #6
0
/// TryStaticMemberPointerUpcast - Tests whether a conversion according to
/// C++ 5.2.9p9 is valid:
///
///   An rvalue of type "pointer to member of D of type cv1 T" can be
///   converted to an rvalue of type "pointer to member of B of type cv2 T",
///   where B is a base class of D [...].
///
TryStaticCastResult
TryStaticMemberPointerUpcast(Sema &Self, QualType SrcType, QualType DestType,
                             const SourceRange &OpRange)
{
  const MemberPointerType *SrcMemPtr = SrcType->getAsMemberPointerType();
  if (!SrcMemPtr)
    return TSC_NotApplicable;
  const MemberPointerType *DestMemPtr = DestType->getAsMemberPointerType();
  if (!DestMemPtr)
    return TSC_NotApplicable;

  // T == T, modulo cv
  if (Self.Context.getCanonicalType(
        SrcMemPtr->getPointeeType().getUnqualifiedType()) !=
      Self.Context.getCanonicalType(DestMemPtr->getPointeeType().
                                    getUnqualifiedType()))
    return TSC_NotApplicable;

  // B base of D
  QualType SrcClass(SrcMemPtr->getClass(), 0);
  QualType DestClass(DestMemPtr->getClass(), 0);
  BasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/false,
                  /*DetectVirtual=*/true);
  if (!Self.IsDerivedFrom(SrcClass, DestClass, Paths)) {
    return TSC_NotApplicable;
  }

  // B is a base of D. But is it an allowed base? If not, it's a hard error.
  if (Paths.isAmbiguous(DestClass)) {
    Paths.clear();
    Paths.setRecordingPaths(true);
    bool StillOkay = Self.IsDerivedFrom(SrcClass, DestClass, Paths);
    assert(StillOkay);
    StillOkay = StillOkay;
    std::string PathDisplayStr = Self.getAmbiguousPathsDisplayString(Paths);
    Self.Diag(OpRange.getBegin(), diag::err_ambiguous_memptr_conv)
      << 1 << SrcClass << DestClass << PathDisplayStr << OpRange;
    return TSC_Failed;
  }

  if (const RecordType *VBase = Paths.getDetectedVirtual()) {
    Self.Diag(OpRange.getBegin(), diag::err_memptr_conv_via_virtual)
      << SrcClass << DestClass << QualType(VBase, 0) << OpRange;
    return TSC_Failed;
  }

  // FIXME: Test accessibility.

  return TSC_Success;
}
/// \brief Get a StringRef representing a SourceRange.
static StringRef getAsString(const MatchFinder::MatchResult &Result,
                             SourceRange R) {
  const SourceManager &SM = *Result.SourceManager;
  // Don't even try to resolve macro or include contraptions. Not worth emitting
  // a fixit for.
  if (R.getBegin().isMacroID() ||
      !SM.isWrittenInSameFile(R.getBegin(), R.getEnd()))
    return StringRef();

  const char *Begin = SM.getCharacterData(R.getBegin());
  const char *End = SM.getCharacterData(Lexer::getLocForEndOfToken(
      R.getEnd(), 0, SM, Result.Context->getLangOpts()));

  return StringRef(Begin, End - Begin);
}
예제 #8
0
void RemoveNamespace::removeLastNamespaceFromUsingDecl(
       const UsingDirectiveDecl *D, const NamespaceDecl *ND)
{
  SourceLocation IdLocStart = D->getIdentLocation();
  SourceRange DeclSourceRange = D->getSourceRange();
  SourceLocation DeclLocStart = DeclSourceRange.getBegin();

  const char *IdStartBuf = SrcManager->getCharacterData(IdLocStart);
  const char *DeclStartBuf = SrcManager->getCharacterData(DeclLocStart);

  unsigned Count = 0;
  int Offset = 0;
  while (IdStartBuf != DeclStartBuf) {
    if (*IdStartBuf != ':') {
      IdStartBuf--;
      Offset--;
      continue;
    }

    Count++;
    if (Count == 2) {
      break;
    }
    Offset--;
    IdStartBuf--;
  }
  TransAssert((Count == 2) && "Bad NestedNamespaceSpecifier!");
  TransAssert((Offset < 0) && "Bad Offset Value!");
  IdLocStart = IdLocStart.getLocWithOffset(Offset);

  TheRewriter.RemoveText(IdLocStart,
                         ND->getNameAsString().length() - Offset);
}
예제 #9
0
void RemoveUnusedStructField::removeOneInitExpr(const Expr *E)
{
  TransAssert(NumFields && "NumFields cannot be zero!");
  if (NumFields == 1) {
    RewriteHelper->replaceExpr(E, "");
    return;
  }

  SourceRange ExpRange = E->getSourceRange();
  SourceLocation StartLoc = ExpRange.getBegin();
  SourceLocation EndLoc = ExpRange.getEnd();
  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));
}
void ASTDumper::dumpSourceRange(SourceRange R) {
  // Can't translate locations if a SourceManager isn't available.
  if (!SM)
    return;

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

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

}
예제 #11
0
bool RVASTVisitor::rewriteFuncDecl(FunctionDecl *FD)
{
  DeclarationNameInfo NameInfo = FD->getNameInfo();
  SourceLocation NameInfoStartLoc = NameInfo.getBeginLoc();

  SourceRange FuncDefRange = FD->getSourceRange();
  SourceLocation FuncStartLoc = FuncDefRange.getBegin();
  
  const char *FuncStartBuf =
      ConsumerInstance->SrcManager->getCharacterData(FuncStartLoc);
  const char *NameInfoStartBuf =
      ConsumerInstance->SrcManager->getCharacterData(NameInfoStartLoc);
  if (FuncStartBuf == NameInfoStartBuf)
    return true;

  int Offset = NameInfoStartBuf - FuncStartBuf;

  NameInfoStartBuf--;
  while ((*NameInfoStartBuf == '(') || (*NameInfoStartBuf == ' ') ||
         (*NameInfoStartBuf == '\t') || (*NameInfoStartBuf == '\n')) {
    Offset--;
    NameInfoStartBuf--;
  }

  TransAssert(Offset >= 0);
  ConsumerInstance->Rewritten = true;
  return !(ConsumerInstance->TheRewriter.ReplaceText(FuncStartLoc, 
                 Offset, "void "));
}
예제 #12
0
// ISSUE: we will have bad transformation for the case below:
// typedef struct S;
// S *s;
// ==>
// typedef
// int *s;
// This is bad because we don't catch the implicit declaration of struct S.
// But hopefully peephole pass will remove the keyword typedef,
// then we will be fine.
void EmptyStructToInt::removeRecordDecls(void)
{
  for (RecordDecl::redecl_iterator I = TheRecordDecl->redecls_begin(),
      E = TheRecordDecl->redecls_end(); I != E; ++I) {

    const RecordDecl *RD = dyn_cast<RecordDecl>(*I);
    SourceRange Range = RD->getSourceRange();
    SourceLocation LocEnd = Range.getEnd();
    SourceLocation SemiLoc = 
      Lexer::findLocationAfterToken(LocEnd, 
                                    tok::semi,
                                    *SrcManager,
                                    Context->getLangOpts(),
                                    /*SkipTrailingWhitespaceAndNewLine=*/true);
    // handle cases such as 
    // struct S {} s;
    if (SemiLoc.isInvalid()) {
      if (!RD->isThisDeclarationADefinition())
        return;
      SourceLocation RBLoc = RD->getRBraceLoc();
      if (RBLoc.isInvalid())
        return;
      RewriteHelper->removeTextFromLeftAt(SourceRange(RBLoc, RBLoc),
                                          '{', RBLoc);
      Rewritten = true;
    }
    else {
      LocEnd = RewriteHelper->getEndLocationUntil(Range, ';');
      TheRewriter.RemoveText(SourceRange(Range.getBegin(), LocEnd));
      Rewritten = true;
    }
  }
}
void ExpandModularHeadersPPCallbacks::MacroExpands(const Token &MacroNameTok,
                                                   const MacroDefinition &,
                                                   SourceRange Range,
                                                   const MacroArgs *) {
  // FIME: Figure out whether it's the right location to parse to.
  parseToLocation(Range.getBegin());
}
예제 #14
0
/// Tests whether a conversion according to N2844 is valid.
TryStaticCastResult
TryLValueToRValueCast(Sema &Self, Expr *SrcExpr, QualType DestType,
                      const SourceRange &OpRange)
{
  // N2844 5.2.9p3: An lvalue of type "cv1 T1" can be cast to type "rvalue
  //   reference to cv2 T2" if "cv2 T2" is reference-compatible with "cv1 T1".
  const RValueReferenceType *R = DestType->getAsRValueReferenceType();
  if (!R)
    return TSC_NotApplicable;

  if (SrcExpr->isLvalue(Self.Context) != Expr::LV_Valid)
    return TSC_NotApplicable;

  // Because we try the reference downcast before this function, from now on
  // this is the only cast possibility, so we issue an error if we fail now.
  bool DerivedToBase;
  if (Self.CompareReferenceRelationship(SrcExpr->getType(), R->getPointeeType(),
                                        DerivedToBase) <
        Sema::Ref_Compatible_With_Added_Qualification) {
    Self.Diag(OpRange.getBegin(), diag::err_bad_lvalue_to_rvalue_cast)
      << SrcExpr->getType() << R->getPointeeType() << OpRange;
    return TSC_Failed;
  }

  // FIXME: Similar to CheckReferenceInit, we actually need more AST annotation
  // than nothing.
  return TSC_Success;
}
void NSAutoreleasePoolChecker::checkPreObjCMessage(ObjCMessage msg,
                                                   CheckerContext &C) const {
  
  const Expr *receiver = msg.getInstanceReceiver();
  if (!receiver)
    return;
  
  // FIXME: Enhance with value-tracking information instead of consulting
  // the type of the expression.
  const ObjCObjectPointerType* PT =
    receiver->getType()->getAs<ObjCObjectPointerType>();
  
  if (!PT)
    return;  
  const ObjCInterfaceDecl *OD = PT->getInterfaceDecl();
  if (!OD)
    return;  
  if (!OD->getIdentifier()->getName().equals("NSAutoreleasePool"))
    return;

  if (releaseS.isNull())
    releaseS = GetNullarySelector("release", C.getASTContext());
  // Sending 'release' message?
  if (msg.getSelector() != releaseS)
    return;
                     
  SourceRange R = msg.getSourceRange();

  C.getBugReporter().EmitBasicReport("Use -drain instead of -release",
    "API Upgrade (Apple)",
    "Use -drain instead of -release when using NSAutoreleasePool "
    "and garbage collection", R.getBegin(), &R, 1);
}
static void addUsage(IdentifierNamingCheck::NamingCheckFailureMap &Failures,
                     const IdentifierNamingCheck::NamingCheckId &Decl,
                     SourceRange Range) {
  // Do nothing if the provided range is invalid.
  if (Range.getBegin().isInvalid() || Range.getEnd().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(Range.getBegin().getRawEncoding()).second)
    return;

  Failure.ShouldFix = Failure.ShouldFix && !Range.getBegin().isMacroID() &&
                      !Range.getEnd().isMacroID();
}
RawComment::RawComment(const SourceManager &SourceMgr, SourceRange SR,
                       bool Merged, bool ParseAllComments) :
    Range(SR), RawTextValid(false), BriefTextValid(false),
    IsAttached(false), IsAlmostTrailingComment(false),
    ParseAllComments(ParseAllComments),
    BeginLineValid(false), EndLineValid(false) {
  // Extract raw comment text, if possible.
  if (SR.getBegin() == SR.getEnd() || getRawText(SourceMgr).empty()) {
    Kind = RCK_Invalid;
    return;
  }

  if (!Merged) {
    // Guess comment kind.
    std::pair<CommentKind, bool> K = getCommentKind(RawText, ParseAllComments);
    Kind = K.first;
    IsTrailingComment = K.second;

    IsAlmostTrailingComment = RawText.startswith("//<") ||
                                 RawText.startswith("/*<");
  } else {
    Kind = RCK_Merged;
    IsTrailingComment = mergedCommentIsTrailingComment(RawText);
  }
}
예제 #18
0
void PCHDeclWriter::VisitObjCContainerDecl(ObjCContainerDecl *D) {
  VisitNamedDecl(D);
  SourceRange R = D->getAtEndRange();
  Writer.AddSourceLocation(R.getBegin(), Record);
  Writer.AddSourceLocation(R.getEnd(), Record);
  // Abstract class (no need to define a stable pch::DECL code).
}
예제 #19
0
bool PreprocessingRecord::rangeIntersectsConditionalDirective(
                                                      SourceRange Range) const {
  if (Range.isInvalid())
    return false;

  CondDirectiveLocsTy::const_iterator
    low = std::lower_bound(CondDirectiveLocs.begin(), CondDirectiveLocs.end(),
                           Range.getBegin(), CondDirectiveLoc::Comp(SourceMgr));
  if (low == CondDirectiveLocs.end())
    return false;

  if (SourceMgr.isBeforeInTranslationUnit(Range.getEnd(), low->getLoc()))
    return false;

  CondDirectiveLocsTy::const_iterator
    upp = std::upper_bound(low, CondDirectiveLocs.end(),
                           Range.getEnd(), CondDirectiveLoc::Comp(SourceMgr));
  unsigned uppIdx;
  if (upp != CondDirectiveLocs.end())
    uppIdx = upp->getIdx();
  else
    uppIdx = 0;

  return low->getIdx() != uppIdx;
}
bool ReduceClassTemplateParameter::reducePartialSpec(
       const ClassTemplatePartialSpecializationDecl *PartialD)
{
  const CXXRecordDecl *CXXRD = TheClassTemplateDecl->getTemplatedDecl();
  // it CXXRD has definition, skip it to avoid duplication
  if (CXXRD->hasDefinition())
    return false;

  if (!isValidForReduction(PartialD))
    return false;
  
  const ASTTemplateArgumentListInfo *ArgList = 
    PartialD->getTemplateArgsAsWritten();
  const TemplateArgumentLoc *ArgLocs = ArgList->getTemplateArgs();
  unsigned NumArgsAsWritten = ArgList->NumTemplateArgs;
  
  const TemplateArgumentLoc FirstArgLoc = ArgLocs[0];
  SourceRange FirstRange = FirstArgLoc.getSourceRange();
  SourceLocation StartLoc = FirstRange.getBegin();

  const TemplateArgumentLoc LastArgLoc = ArgLocs[NumArgsAsWritten - 1];
  SourceRange LastRange = LastArgLoc.getSourceRange();
  SourceLocation EndLoc = 
    RewriteHelper->getEndLocationUntil(LastRange, '>');

  RewriteHelper->removeTextFromLeftAt(SourceRange(StartLoc, EndLoc), '<', EndLoc);
  return true;
}
예제 #21
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));
}
void TransformActionsImpl::commitReplace(SourceRange range,
                                         SourceRange replacementRange) {
  RangeComparison comp = CharRange::compare(replacementRange, range,
                                               Ctx.getSourceManager(), PP);
  assert(comp == Range_Contained);
  if (comp != Range_Contained)
    return; // Although we asserted, be extra safe for release build.
  if (range.getBegin() != replacementRange.getBegin())
    addRemoval(CharSourceRange::getCharRange(range.getBegin(),
                                             replacementRange.getBegin()));
  if (replacementRange.getEnd() != range.getEnd())
    addRemoval(CharSourceRange::getTokenRange(
                                  getLocForEndOfToken(replacementRange.getEnd(),
                                                      Ctx.getSourceManager(), PP),
                                  range.getEnd()));
}
void DefaultArgumentsCheck::check(const MatchFinder::MatchResult &Result) {
  if (const auto *S =
          Result.Nodes.getNodeAs<CXXDefaultArgExpr>("stmt")) {
    diag(S->getUsedLocation(),
         "calling a function that uses a default argument is disallowed");
    diag(S->getParam()->getBeginLoc(), "default parameter was declared here",
         DiagnosticIDs::Note);
  } else if (const ParmVarDecl *D =
          Result.Nodes.getNodeAs<ParmVarDecl>("decl")) {
    SourceRange DefaultArgRange = D->getDefaultArgRange();

    if (DefaultArgRange.getEnd() != D->getEndLoc()) {
      return;
    } else if (DefaultArgRange.getBegin().isMacroID()) {
      diag(D->getBeginLoc(),
           "declaring a parameter with a default argument is disallowed");
    } else {
      SourceLocation StartLocation =
          D->getName().empty() ? D->getBeginLoc() : D->getLocation();

      SourceRange RemovalRange(Lexer::getLocForEndOfToken(
             StartLocation, 0,
             *Result.SourceManager,
             Result.Context->getLangOpts()
           ),
           DefaultArgRange.getEnd()
         );

      diag(D->getBeginLoc(),
           "declaring a parameter with a default argument is disallowed")
          << D << FixItHint::CreateRemoval(RemovalRange);
    }
  }
}
예제 #24
0
파일: ARCMT.cpp 프로젝트: CTSRD-TESLA/clang
bool CapturedDiagList::clearDiagnostic(ArrayRef<unsigned> IDs,
                                       SourceRange range) {
  if (range.isInvalid())
    return false;

  bool cleared = false;
  ListTy::iterator I = List.begin();
  while (I != List.end()) {
    FullSourceLoc diagLoc = I->getLocation();
    if ((IDs.empty() || // empty means clear all diagnostics in the range.
         std::find(IDs.begin(), IDs.end(), I->getID()) != IDs.end()) &&
        !diagLoc.isBeforeInTranslationUnitThan(range.getBegin()) &&
        (diagLoc == range.getEnd() ||
           diagLoc.isBeforeInTranslationUnitThan(range.getEnd()))) {
      cleared = true;
      ListTy::iterator eraseS = I++;
      while (I != List.end() && I->getLevel() == DiagnosticsEngine::Note)
        ++I;
      // Clear the diagnostic and any notes following it.
      List.erase(eraseS, I);
      continue;
    }

    ++I;
  }

  return cleared;
}
예제 #25
0
bool RewriteUtils::getEntireDeclGroupStrAndRemove(DeclGroupRef DGR,
                                                  std::string &Str)
{
  Decl *FirstD, *LastD;
  if (DGR.isSingleDecl()) {
    FirstD = DGR.getSingleDecl();
    LastD = FirstD;
  }
  else {
    DeclGroupRef::iterator I = DGR.begin();
    FirstD = (*I);

    DeclGroupRef::iterator E = DGR.end();
    --E;
    LastD = (*E);
  }

  SourceRange FirstRange = FirstD->getSourceRange();
  SourceLocation StartLoc = FirstRange.getBegin();
  SourceRange LastRange = LastD->getSourceRange();
  SourceLocation EndLoc = getEndLocationUntil(LastRange, ';');

  getStringBetweenLocs(Str, StartLoc, EndLoc);
  return !TheRewriter->RemoveText(SourceRange(StartLoc, EndLoc));
}
예제 #26
0
bool ClangDocHTML::HandleComment(Preprocessor &PP, SourceRange Comment) 
{
	if(Comment.isValid()) 
	{		
		if(astConsumer->sourceManager->isInSystemHeader(Comment.getBegin()))
		{
			return false;
		}
		
		/*
		bool bInvalid = false;
		const char *cbegin = astConsumer->sourceManager->getCharacterData(Comment.getBegin(), &bInvalid);
		const char *cend = astConsumer->sourceManager->getCharacterData(Comment.getEnd(), &bInvalid);
		llvm::StringRef string = llvm::StringRef(cbegin, cend-cbegin);*/

		//Decl *decl = 0;

		/*if(string.startswith("///<"))
		{
			decl = lastDecl;
			decl->print(*Out);
		}*/

		commentsList.push_back(Comment);
		//lastComment = commentsByDecl.insert(CommentsByDeclPair(decl, string) ); 
		
		//*Out << string << "<br/>\n";
	}
	return false;
}
void ReplaceFunctionDefWithDecl::removeCtorInitializers(
       const CXXConstructorDecl *Ctor)
{
  if (!getNumWrittenInitializers(Ctor))
    return;
  CXXConstructorDecl::init_const_iterator I = Ctor->init_begin();
  while (!(*I)->isWritten())
    ++I;
  const CXXCtorInitializer *FirstInit = (*I);
  SourceRange Range = FirstInit->getSourceRange();
  SourceLocation LocStart = Range.getBegin();
  // RewriteHelper->removeTextFromLeftAt(Range, ':', 
  //                                     LocStart.getLocWithOffset(-1));
  // make sure we handle cases like:
  // namespace NS { struct A {}; }
  // struct B : NS::A { B() : NS::A() {} };
  SourceLocation Loc = RewriteHelper->getLocationFromLeftUntil(LocStart, ':');
  Loc = RewriteHelper->getLocationFromLeftUntil(LocStart, ')');
  TheRewriter.RemoveText(SourceRange(Loc.getLocWithOffset(1), 
                                     LocStart.getLocWithOffset(-1)));
  CXXConstructorDecl::init_const_iterator E = Ctor->init_end();
  --E;
  while (!(*E)->isWritten())
    --E;
  const CXXCtorInitializer *LastInit = (*E);
  TransAssert(LastInit->isWritten() && "Init is not written!");
  SourceLocation LocEnd = LastInit->getSourceRange().getEnd();
  TheRewriter.RemoveText(SourceRange(LocStart, LocEnd));
}
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(), "}");
}
// ISSUE: The transformation is known to go wrong in the following case:
// template<typename T1, typename T2> struct S;
// template<typename T1, typename T2> struct S<T2, T1>;
void ReduceClassTemplateParameter::removeParameterFromPartialSpecs()
{
  SmallVector<ClassTemplatePartialSpecializationDecl *, 10> PartialDecls;
  TheClassTemplateDecl->getPartialSpecializations(PartialDecls);

  for (SmallVector<ClassTemplatePartialSpecializationDecl *, 10>::iterator 
         I = PartialDecls.begin(), E = PartialDecls.end(); I != E; ++I) {
    const ClassTemplatePartialSpecializationDecl *PartialD = (*I);
    
    const ASTTemplateArgumentListInfo *ArgList = 
      PartialD->getTemplateArgsAsWritten();
    const TemplateArgumentLoc *ArgLocs = ArgList->getTemplateArgs();
    unsigned NumArgs = ArgList->NumTemplateArgs;
    
    if (!ArgLocs)
      continue;

    // handle a special case where we could reduce a partial specialization
    // to a class template definition, e.g.:
    //   template<typename T1, typename T2> struct A;
    //   template<typename T1> struct A<T1, int> { };
    // ==>
    //   template<typename T1> struct A;
    //   template<typename T1> struct A { };
    if (reducePartialSpec(PartialD))
      continue;

    if ((TheParameterIndex >= NumArgs) && hasDefaultArg)
      return;

    TransAssert((TheParameterIndex < NumArgs) && 
                 "Bad NumArgs from partial template decl!");
    TemplateArgumentLoc ArgLoc = ArgLocs[TheParameterIndex];

    TemplateArgument Arg = ArgLoc.getArgument();
    removeOneParameterFromPartialDecl(PartialD, Arg);
     
    SourceRange Range = ArgLoc.getSourceRange();

    if (NumArgs == 1) {
      SourceLocation StartLoc = Range.getBegin();
      SourceLocation EndLoc = 
        RewriteHelper->getEndLocationUntil(Range, '>');
      EndLoc = EndLoc.getLocWithOffset(-1);
      TheRewriter.RemoveText(SourceRange(StartLoc, EndLoc));
    }
    else if ((TheParameterIndex + 1) == NumArgs) {
      // Seems there is no getRAngleLoc() utility for 
      // template arguments from a partial specialization
      SourceLocation EndLoc = 
        RewriteHelper->getEndLocationUntil(Range, '>');
      EndLoc = EndLoc.getLocWithOffset(-1);
      RewriteHelper->removeTextFromLeftAt(Range, ',', EndLoc);
    }
    else {
      RewriteHelper->removeTextUntil(Range, ',');
    }
  }
}
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;
}