Ejemplo n.º 1
0
void XCTMigrator::migrateRef(NamedDecl *D, SourceLocation Loc) {
  if (!D || Loc.isInvalid())
    return;

  llvm::DenseMap<IdentifierInfo *, IdentifierInfo *>::iterator DI =
      DeclsMap.find(D->getDeclName().getAsIdentifierInfo());
  if (DI == DeclsMap.end())
    return;
  if (!isFromSenTestInclude(D->getLocation()) || isFromSenTestInclude(Loc))
    return;

  assert(DI->second);
  edit::Commit commit(Editor);
  commit.replace(Loc, DI->second->getName());
  Editor.commit(commit);
}
Ejemplo n.º 2
0
CXSourceLocation lfort_getLocationForOffset(CXProgram tu,
                                            CXFile file,
                                            unsigned offset) {
  if (!tu || !file)
    return lfort_getNullLocation();
  
  ASTUnit *CXXUnit = static_cast<ASTUnit *>(tu->PgmData);

  SourceLocation SLoc 
    = CXXUnit->getLocation(static_cast<const FileEntry *>(file), offset);

  if (SLoc.isInvalid())
    return lfort_getNullLocation();
  
  return cxloc::translateSourceLocation(CXXUnit->getASTContext(), SLoc);
}
Ejemplo n.º 3
0
void PrettyStackTraceDecl::print(llvm::raw_ostream &OS) const {
  SourceLocation TheLoc = Loc;
  if (TheLoc.isInvalid() && TheDecl)
    TheLoc = TheDecl->getLocation();

  if (TheLoc.isValid()) {
    TheLoc.print(OS, SM);
    OS << ": ";
  }

  OS << Message;

  if (NamedDecl *DN = dyn_cast_or_null<NamedDecl>(TheDecl))
    OS << " '" << DN->getQualifiedNameAsString() << '\'';
  OS << '\n';
}
Ejemplo n.º 4
0
 // Parses module references in the given lines. Returns the module references,
 // and a pointer to the first "main code" line if that is adjacent to the
 // affected lines of module references, nullptr otherwise.
 std::pair<SmallVector<JsModuleReference, 16>, AnnotatedLine*>
 parseModuleReferences(const AdditionalKeywords &Keywords,
                       SmallVectorImpl<AnnotatedLine *> &AnnotatedLines) {
   SmallVector<JsModuleReference, 16> References;
   SourceLocation Start;
   AnnotatedLine *FirstNonImportLine = nullptr;
   bool AnyImportAffected = false;
   for (auto Line : AnnotatedLines) {
     Current = Line->First;
     LineEnd = Line->Last;
     skipComments();
     if (Start.isInvalid() || References.empty())
       // After the first file level comment, consider line comments to be part
       // of the import that immediately follows them by using the previously
       // set Start.
       Start = Line->First->Tok.getLocation();
     if (!Current) {
       // Only comments on this line. Could be the first non-import line.
       FirstNonImportLine = Line;
       continue;
     }
     JsModuleReference Reference;
     Reference.Range.setBegin(Start);
     if (!parseModuleReference(Keywords, Reference)) {
       if (!FirstNonImportLine)
         FirstNonImportLine = Line; // if no comment before.
       break;
     }
     FirstNonImportLine = nullptr;
     AnyImportAffected = AnyImportAffected || Line->Affected;
     Reference.Range.setEnd(LineEnd->Tok.getEndLoc());
     DEBUG({
       llvm::dbgs() << "JsModuleReference: {"
                    << "is_export: " << Reference.IsExport
                    << ", cat: " << Reference.Category
                    << ", url: " << Reference.URL
                    << ", prefix: " << Reference.Prefix;
       for (size_t i = 0; i < Reference.Symbols.size(); ++i)
         llvm::dbgs() << ", " << Reference.Symbols[i].Symbol << " as "
                      << Reference.Symbols[i].Alias;
       llvm::dbgs() << ", text: " << getSourceText(Reference.Range);
       llvm::dbgs() << "}\n";
     });
     References.push_back(Reference);
     Start = SourceLocation();
   }
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;
}
Ejemplo n.º 6
0
void TextDiagnosticPrinter::
PrintIncludeStack(SourceLocation Loc, const SourceManager &SM) {
  if (Loc.isInvalid()) return;

  PresumedLoc PLoc = SM.getPresumedLoc(Loc);
  if (PLoc.isInvalid())
    return;
  
  // Print out the other include frames first.
  PrintIncludeStack(PLoc.getIncludeLoc(), SM);

  if (DiagOpts->ShowLocation)
    OS << "In file included from " << PLoc.getFilename()
       << ':' << PLoc.getLine() << ":\n";
  else
    OS << "In included file:\n";
}
Ejemplo n.º 7
0
/// \brief Helper to recursivly walk up the include stack and print each layer
/// on the way back down.
void TextDiagnostic::emitIncludeStackRecursively(SourceLocation Loc) {
    if (Loc.isInvalid())
        return;

    PresumedLoc PLoc = SM.getPresumedLoc(Loc);
    if (PLoc.isInvalid())
        return;

    // Emit the other include frames first.
    emitIncludeStackRecursively(PLoc.getIncludeLoc());

    if (DiagOpts.ShowLocation)
        OS << "In file included from " << PLoc.getFilename()
           << ':' << PLoc.getLine() << ":\n";
    else
        OS << "In included file:\n";
}
void MakeSmartPtrCheck::checkReset(SourceManager &SM,
                                   const CXXMemberCallExpr *Reset,
                                   const CXXNewExpr *New) {
  const auto *Expr = cast<MemberExpr>(Reset->getCallee());
  SourceLocation OperatorLoc = Expr->getOperatorLoc();
  SourceLocation ResetCallStart = Reset->getExprLoc();
  SourceLocation ExprStart = Expr->getLocStart();
  SourceLocation ExprEnd =
      Lexer::getLocForEndOfToken(Expr->getLocEnd(), 0, SM, getLangOpts());

  bool InMacro = ExprStart.isMacroID();

  if (InMacro && IgnoreMacros) {
    return;
  }

  // There are some cases where we don't have operator ("." or "->") of the
  // "reset" expression, e.g. call "reset()" method directly in the subclass of
  // "std::unique_ptr<>". We skip these cases.
  if (OperatorLoc.isInvalid()) {
    return;
  }

  auto Diag = diag(ResetCallStart, "use %0 instead")
              << MakeSmartPtrFunctionName;

  // Disable the fix in macros.
  if (InMacro) {
    return;
  }

  if (!replaceNew(Diag, New, SM)) {
    return;
  }

  Diag << FixItHint::CreateReplacement(
      CharSourceRange::getCharRange(OperatorLoc, ExprEnd),
      (llvm::Twine(" = ") + MakeSmartPtrFunctionName + "<" +
       GetNewExprName(New, SM, getLangOpts()) + ">")
          .str());

  if (Expr->isArrow())
    Diag << FixItHint::CreateInsertion(ExprStart, "*");

  insertHeader(Diag, SM.getFileID(OperatorLoc));
}
Ejemplo n.º 9
0
bool CXIndexDataConsumer::handleReference(const NamedDecl *D, SourceLocation Loc,
                                      CXCursor Cursor,
                                      const NamedDecl *Parent,
                                      const DeclContext *DC,
                                      const Expr *E,
                                      CXIdxEntityRefKind Kind) {
  if (!CB.indexEntityReference)
    return false;

  if (!D)
    return false;
  if (Loc.isInvalid())
    return false;
  if (!shouldIndexFunctionLocalSymbols() && isFunctionLocalDecl(D))
    return false;
  if (isNotFromSourceFile(D->getLocation()))
    return false;
  if (D->isImplicit() && shouldIgnoreIfImplicit(D))
    return false;

  if (shouldSuppressRefs()) {
    if (markEntityOccurrenceInFile(D, Loc))
      return false; // already occurred.
  }

  ScratchAlloc SA(*this);
  EntityInfo RefEntity, ParentEntity;
  getEntityInfo(D, RefEntity, SA);
  if (!RefEntity.USR)
    return false;

  getEntityInfo(Parent, ParentEntity, SA);

  ContainerInfo Container;
  getContainerInfo(DC, Container);

  CXIdxEntityRefInfo Info = { Kind,
                              Cursor,
                              getIndexLoc(Loc),
                              &RefEntity,
                              Parent ? &ParentEntity : nullptr,
                              &Container };
  CB.indexEntityReference(ClientData, &Info);
  return true;
}
Ejemplo n.º 10
0
void BackendConsumer::EmitOptimizationRemark(
    const llvm::DiagnosticInfoOptimizationRemarkBase &D, unsigned DiagID) {
  // We only support remarks.
  assert(D.getSeverity() == llvm::DS_Remark);

  SourceManager &SourceMgr = Context->getSourceManager();
  FileManager &FileMgr = SourceMgr.getFileManager();
  StringRef Filename;
  unsigned Line, Column;
  D.getLocation(&Filename, &Line, &Column);
  SourceLocation DILoc;
  const FileEntry *FE = FileMgr.getFile(Filename);
  if (FE && Line > 0) {
    // If -gcolumn-info was not used, Column will be 0. This upsets the
    // source manager, so pass 1 if Column is not set.
    DILoc = SourceMgr.translateFileLineCol(FE, Line, Column ? Column : 1);
  }

  // If a location isn't available, try to approximate it using the associated
  // function definition. We use the definition's right brace to differentiate
  // from diagnostics that genuinely relate to the function itself.
  FullSourceLoc Loc(DILoc, SourceMgr);
  if (Loc.isInvalid())
    if (const Decl *FD = Gen->GetDeclForMangledName(D.getFunction().getName()))
      Loc = FD->getASTContext().getFullLoc(FD->getBodyRBrace());

  Diags.Report(Loc, DiagID) << AddFlagValue(D.getPassName())
                            << D.getMsg().str();

  if (Line == 0)
    // If we could not extract a source location for the diagnostic,
    // inform the user how they can get source locations back.
    //
    // FIXME: We should really be generating !srcloc annotations when
    // -Rpass is used. !srcloc annotations need to be emitted in
    // approximately the same spots as !dbg nodes.
    Diags.Report(Loc, diag::note_fe_backend_optimization_remark_missing_loc);
  else if (DILoc.isInvalid())
    // If we were not able to translate the file:line:col information
    // back to a SourceLocation, at least emit a note stating that
    // we could not translate this location. This can happen in the
    // case of #line directives.
    Diags.Report(Loc, diag::note_fe_backend_optimization_remark_invalid_loc)
        << Filename << Line << Column;
}
Ejemplo n.º 11
0
static bool rewriteToNSEnumDecl(const EnumDecl *EnumDcl,
                                const TypedefDecl *TypedefDcl,
                                const NSAPI &NS, edit::Commit &commit,
                                bool IsNSIntegerType) {
  std::string ClassString =
    IsNSIntegerType ? "typedef NS_ENUM(NSInteger, " : "typedef NS_OPTIONS(NSUInteger, ";
  ClassString += TypedefDcl->getIdentifier()->getName();
  ClassString += ')';
  SourceRange R(EnumDcl->getLocStart(), EnumDcl->getLocStart());
  commit.replace(R, ClassString);
  SourceLocation EndOfTypedefLoc = TypedefDcl->getLocEnd();
  EndOfTypedefLoc = trans::findLocationAfterSemi(EndOfTypedefLoc, NS.getASTContext());
  if (!EndOfTypedefLoc.isInvalid()) {
    commit.remove(SourceRange(TypedefDcl->getLocStart(), EndOfTypedefLoc));
    return true;
  }
  return false;
}
Ejemplo n.º 12
0
/// \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());
}
Ejemplo n.º 13
0
void BackendConsumer::OptimizationRemarkHandler(
    const llvm::DiagnosticInfoOptimizationRemark &D) {
  // We only support remarks.
  assert(D.getSeverity() == llvm::DS_Remark);

  // Optimization remarks are active only if -Rpass=regexp is given and the
  // regular expression pattern in 'regexp' matches the name of the pass
  // name in \p D.
  if (CodeGenOpts.OptimizationRemarkPattern &&
      CodeGenOpts.OptimizationRemarkPattern->match(D.getPassName())) {
    SourceManager &SourceMgr = Context->getSourceManager();
    FileManager &FileMgr = SourceMgr.getFileManager();
    StringRef Filename;
    unsigned Line, Column;
    D.getLocation(&Filename, &Line, &Column);
    SourceLocation Loc;
    const FileEntry *FE = FileMgr.getFile(Filename);
    if (FE && Line > 0) {
      // If -gcolumn-info was not used, Column will be 0. This upsets the
      // source manager, so if Column is not set, set it to 1.
      if (Column == 0)
        Column = 1;
      Loc = SourceMgr.translateFileLineCol(FE, Line, Column);
    }
    Diags.Report(Loc, diag::remark_fe_backend_optimization_remark)
        << AddFlagValue(D.getPassName()) << D.getMsg().str();

    if (Line == 0)
      // If we could not extract a source location for the diagnostic,
      // inform the user how they can get source locations back.
      //
      // FIXME: We should really be generating !srcloc annotations when
      // -Rpass is used. !srcloc annotations need to be emitted in
      // approximately the same spots as !dbg nodes.
      Diags.Report(diag::note_fe_backend_optimization_remark_missing_loc);
    else if (Loc.isInvalid())
      // If we were not able to translate the file:line:col information
      // back to a SourceLocation, at least emit a note stating that
      // we could not translate this location. This can happen in the
      // case of #line directives.
      Diags.Report(diag::note_fe_backend_optimization_remark_invalid_loc)
        << Filename << Line << Column;
  }
}
Ejemplo n.º 14
0
static void WriteSourceLocation(llvm::raw_ostream &OS, 
                                SourceManager *SM,
                                SourceLocation Location) {
  if (!SM || Location.isInvalid()) {
    // If we don't have a source manager or this location is invalid,
    // just write an invalid location.
    WriteUnsigned(OS, 0);
    WriteUnsigned(OS, 0);
    WriteUnsigned(OS, 0);
    return;
  }

  Location = SM->getInstantiationLoc(Location);
  std::pair<FileID, unsigned> Decomposed = SM->getDecomposedLoc(Location);
  
  WriteString(OS, SM->getFileEntryForID(Decomposed.first)->getName());
  WriteUnsigned(OS, SM->getLineNumber(Decomposed.first, Decomposed.second));
  WriteUnsigned(OS, SM->getColumnNumber(Decomposed.first, Decomposed.second));
}
Ejemplo n.º 15
0
/// \brief Helper to recursivly walk up the import stack and print each layer
/// on the way back down.
void DiagnosticRenderer::emitImportStackRecursively(SourceLocation Loc,
                                                    StringRef ModuleName,
                                                    const SourceManager &SM) {
  if (Loc.isInvalid()) {
    return;
  }

  PresumedLoc PLoc = SM.getPresumedLoc(Loc);
  if (PLoc.isInvalid())
    return;

  // Emit the other import frames first.
  std::pair<SourceLocation, StringRef> NextImportLoc
    = SM.getModuleImportLoc(Loc);
  emitImportStackRecursively(NextImportLoc.first, NextImportLoc.second, SM);

  // Emit the inclusion text/note.
  emitImportLocation(Loc, PLoc, ModuleName, SM);
}
void SDiagsWriter::AddLocToRecord(SourceLocation Loc,
                                  RecordDataImpl &Record,
                                  unsigned TokSize) {
  if (Loc.isInvalid()) {
    // Emit a "sentinel" location.
    Record.push_back((unsigned)0); // File.
    Record.push_back((unsigned)0); // Line.
    Record.push_back((unsigned)0); // Column.
    Record.push_back((unsigned)0); // Offset.
    return;
  }

  SourceManager &SM = Diags.getSourceManager();
  Loc = SM.getSpellingLoc(Loc);
  Record.push_back(getEmitFile(Loc));
  Record.push_back(SM.getSpellingLineNumber(Loc));
  Record.push_back(SM.getSpellingColumnNumber(Loc)+TokSize);
  Record.push_back(SM.getFileOffset(Loc));
}
Ejemplo n.º 17
0
void BackendConsumer::EmitOptimizationMessage(
    const llvm::DiagnosticInfoOptimizationBase &D, unsigned DiagID) {
  // We only support warnings and remarks.
  assert(D.getSeverity() == llvm::DS_Remark ||
         D.getSeverity() == llvm::DS_Warning);

  SourceManager &SourceMgr = Context->getSourceManager();
  FileManager &FileMgr = SourceMgr.getFileManager();
  StringRef Filename;
  unsigned Line, Column;
  SourceLocation DILoc;

  if (D.isLocationAvailable()) {
    D.getLocation(&Filename, &Line, &Column);
    const FileEntry *FE = FileMgr.getFile(Filename);
    if (FE && Line > 0) {
      // If -gcolumn-info was not used, Column will be 0. This upsets the
      // source manager, so pass 1 if Column is not set.
      DILoc = SourceMgr.translateFileLineCol(FE, Line, Column ? Column : 1);
    }
  }

  // If a location isn't available, try to approximate it using the associated
  // function definition. We use the definition's right brace to differentiate
  // from diagnostics that genuinely relate to the function itself.
  FullSourceLoc Loc(DILoc, SourceMgr);
  if (Loc.isInvalid())
    if (const Decl *FD = Gen->GetDeclForMangledName(D.getFunction().getName()))
      Loc = FD->getASTContext().getFullLoc(FD->getBodyRBrace());

  Diags.Report(Loc, DiagID)
      << AddFlagValue(D.getPassName() ? D.getPassName() : "")
      << D.getMsg().str();

  if (DILoc.isInvalid() && D.isLocationAvailable())
    // If we were not able to translate the file:line:col information
    // back to a SourceLocation, at least emit a note stating that
    // we could not translate this location. This can happen in the
    // case of #line directives.
    Diags.Report(Loc, diag::note_fe_backend_optimization_remark_invalid_loc)
        << Filename << Line << Column;
}
/// \brief Require that the context specified by SS be complete.
///
/// If SS refers to a type, this routine checks whether the type is
/// complete enough (or can be made complete enough) for name lookup
/// into the DeclContext. A type that is not yet completed can be
/// considered "complete enough" if it is a class/struct/union/enum
/// that is currently being defined. Or, if we have a type that names
/// a class template specialization that is not a complete type, we
/// will attempt to instantiate that class template.
bool Sema::RequireCompleteDeclContext(CXXScopeSpec &SS,
                                      DeclContext *DC) {
  assert(DC != 0 && "given null context");

  if (TagDecl *tag = dyn_cast<TagDecl>(DC)) {
    // If this is a dependent type, then we consider it complete.
    if (tag->isDependentContext())
      return false;

    // If we're currently defining this type, then lookup into the
    // type is okay: don't complain that it isn't complete yet.
    QualType type = Context.getTypeDeclType(tag);
    const TagType *tagType = type->getAs<TagType>();
    if (tagType && tagType->isBeingDefined())
      return false;

    SourceLocation loc = SS.getLastQualifierNameLoc();
    if (loc.isInvalid()) loc = SS.getRange().getBegin();

    // The type must be complete.
    if (RequireCompleteType(loc, type,
                            PDiag(diag::err_incomplete_nested_name_spec)
                              << SS.getRange())) {
      SS.SetInvalid(SS.getRange());
      return true;
    }

    // Fixed enum types are complete, but they aren't valid as scopes
    // until we see a definition, so awkwardly pull out this special
    // case.
    if (const EnumType *enumType = dyn_cast_or_null<EnumType>(tagType)) {
      if (!enumType->getDecl()->isCompleteDefinition()) {
        Diag(loc, diag::err_incomplete_nested_name_spec)
          << type << SS.getRange();
        SS.SetInvalid(SS.getRange());
        return true;
      }
    }
  }

  return false;
}
Ejemplo n.º 19
0
void clang_indexLoc_getFileLocation(CXIdxLoc location,
                                    CXIdxClientFile *indexFile,
                                    CXFile *file,
                                    unsigned *line,
                                    unsigned *column,
                                    unsigned *offset) {
  if (indexFile) *indexFile = 0;
  if (file)   *file = 0;
  if (line)   *line = 0;
  if (column) *column = 0;
  if (offset) *offset = 0;

  SourceLocation Loc = SourceLocation::getFromRawEncoding(location.int_data);
  if (!location.ptr_data[0] || Loc.isInvalid())
    return;

  IndexingContext &IndexCtx =
      *static_cast<IndexingContext*>(location.ptr_data[0]);
  IndexCtx.translateLoc(Loc, indexFile, file, line, column, offset);
}
Ejemplo n.º 20
0
CXSourceLocation clang_getLocationForOffset(CXTranslationUnit TU,
                                            CXFile file,
                                            unsigned offset) {
  if (cxtu::isNotUsableTU(TU)) {
    LOG_BAD_TU(TU);
    return clang_getNullLocation();
  }
  if (!file)
    return clang_getNullLocation();

  ASTUnit *CXXUnit = cxtu::getASTUnit(TU);

  SourceLocation SLoc 
    = CXXUnit->getLocation(static_cast<const FileEntry *>(file), offset);

  if (SLoc.isInvalid())
    return clang_getNullLocation();
  
  return cxloc::translateSourceLocation(CXXUnit->getASTContext(), SLoc);
}
Ejemplo n.º 21
0
bool clang::index::generateUSRForMacro(StringRef MacroName, SourceLocation Loc,
                                       const SourceManager &SM,
                                       SmallVectorImpl<char> &Buf) {
  // Don't generate USRs for things with invalid locations.
  if (MacroName.empty() || Loc.isInvalid())
    return true;

  llvm::raw_svector_ostream Out(Buf);

  // Assume that system headers are sane.  Don't put source location
  // information into the USR if the macro comes from a system header.
  bool ShouldGenerateLocation = !SM.isInSystemHeader(Loc);

  Out << getUSRSpacePrefix();
  if (ShouldGenerateLocation)
    printLoc(Out, Loc, SM, /*IncludeOffset=*/true);
  Out << "@macro@";
  Out << MacroName;
  return false;
}
Ejemplo n.º 22
0
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;
}
Ejemplo n.º 23
0
void lfort_getExpansionLocation(CXSourceLocation location,
                                CXFile *file,
                                unsigned *line,
                                unsigned *column,
                                unsigned *offset) {
  
  if (!isASTUnitSourceLocation(location)) {
    CXLoadedDiagnostic::decodeLocation(location, file, line, column, offset);
    return;
  }

  SourceLocation Loc = SourceLocation::getFromRawEncoding(location.int_data);

  if (!location.ptr_data[0] || Loc.isInvalid()) {
    createNullLocation(file, line, column, offset);
    return;
  }

  const SourceManager &SM =
  *static_cast<const SourceManager*>(location.ptr_data[0]);
  SourceLocation ExpansionLoc = SM.getExpansionLoc(Loc);
  
  // Check that the FileID is invalid on the expansion location.
  // This can manifest in invalid code.
  FileID fileID = SM.getFileID(ExpansionLoc);
  bool Invalid = false;
  const SrcMgr::SLocEntry &sloc = SM.getSLocEntry(fileID, &Invalid);
  if (Invalid || !sloc.isFile()) {
    createNullLocation(file, line, column, offset);
    return;
  }
  
  if (file)
    *file = (void *)SM.getFileEntryForSLocEntry(sloc);
  if (line)
    *line = SM.getExpansionLineNumber(ExpansionLoc);
  if (column)
    *column = SM.getExpansionColumnNumber(ExpansionLoc);
  if (offset)
    *offset = SM.getDecomposedLoc(ExpansionLoc).second;
}
Ejemplo n.º 24
0
bool CXIndexDataConsumer::markEntityOccurrenceInFile(const NamedDecl *D,
                                                 SourceLocation Loc) {
  if (!D || Loc.isInvalid())
    return true;

  SourceManager &SM = Ctx->getSourceManager();
  D = getEntityDecl(D);
  
  std::pair<FileID, unsigned> LocInfo = SM.getDecomposedLoc(SM.getFileLoc(Loc));
  FileID FID = LocInfo.first;
  if (FID.isInvalid())
    return true;
  
  const FileEntry *FE = SM.getFileEntryForID(FID);
  if (!FE)
    return true;
  RefFileOccurrence RefOccur(FE, D);
  std::pair<llvm::DenseSet<RefFileOccurrence>::iterator, bool>
  res = RefFileOccurrences.insert(RefOccur);
  return !res.second; // already in map
}
Ejemplo n.º 25
0
AnalysisConsumer::AnalysisMode
AnalysisConsumer::getModeForDecl(Decl *D, AnalysisMode Mode) {
  if (!Opts->AnalyzeSpecificFunction.empty() &&
      getFunctionName(D) != Opts->AnalyzeSpecificFunction)
    return AM_None;

  // Unless -analyze-all is specified, treat decls differently depending on
  // where they came from:
  // - Main source file: run both path-sensitive and non-path-sensitive checks.
  // - Header files: run non-path-sensitive checks only.
  // - System headers: don't run any checks.
  SourceManager &SM = Ctx->getSourceManager();
  SourceLocation SL = SM.getExpansionLoc(D->getLocation());
  if (!Opts->AnalyzeAll && !SM.isInMainFile(SL)) {
    if (SL.isInvalid() || SM.isInSystemHeader(SL))
      return AM_None;
    return Mode & ~AM_Path;
  }

  return Mode;
}
Ejemplo n.º 26
0
/// \returns true on error.
static bool printLoc(llvm::raw_ostream &OS, SourceLocation Loc,
                     const SourceManager &SM, bool IncludeOffset) {
  if (Loc.isInvalid()) {
    return true;
  }
  Loc = SM.getExpansionLoc(Loc);
  const std::pair<FileID, unsigned> &Decomposed = SM.getDecomposedLoc(Loc);
  const FileEntry *FE = SM.getFileEntryForID(Decomposed.first);
  if (FE) {
    OS << llvm::sys::path::filename(FE->getName());
  } else {
    // This case really isn't interesting.
    return true;
  }
  if (IncludeOffset) {
    // Use the offest into the FileID to represent the location.  Using
    // a line/column can cause us to look back at the original source file,
    // which is expensive.
    OS << '@' << Decomposed.second;
  }
  return false;
}
Ejemplo n.º 27
0
void RewriteBlocks::HandleTopLevelSingleDecl(Decl *D) {
  // Two cases: either the decl could be in the main file, or it could be in a
  // #included file.  If the former, rewrite it now.  If the later, check to see
  // if we rewrote the #include/#import.
  SourceLocation Loc = D->getLocation();
  Loc = SM->getInstantiationLoc(Loc);
  
  // If this is for a builtin, ignore it.
  if (Loc.isInvalid()) return;
  
  if (ObjCInterfaceDecl *MD = dyn_cast<ObjCInterfaceDecl>(D))
    RewriteInterfaceDecl(MD);
  else if (ObjCCategoryDecl *CD = dyn_cast<ObjCCategoryDecl>(D))
    RewriteCategoryDecl(CD);
  else if (ObjCProtocolDecl *PD = dyn_cast<ObjCProtocolDecl>(D))
    RewriteProtocolDecl(PD);

  // If we have a decl in the main file, see if we should rewrite it.
  if (SM->isFromMainFile(Loc))
    HandleDeclInMainFile(D);
  return;
}
Ejemplo n.º 28
0
bool IndexingContext::importedModule(const ImportDecl *ImportD) {
  SourceLocation Loc;
  auto IdLocs = ImportD->getIdentifierLocs();
  if (!IdLocs.empty())
    Loc = IdLocs.front();
  else
    Loc = ImportD->getLocation();
  SourceManager &SM = Ctx->getSourceManager();
  Loc = SM.getFileLoc(Loc);
  if (Loc.isInvalid())
    return true;

  FileID FID;
  unsigned Offset;
  std::tie(FID, Offset) = SM.getDecomposedLoc(Loc);
  if (FID.isInvalid())
    return true;

  bool Invalid = false;
  const SrcMgr::SLocEntry &SEntry = SM.getSLocEntry(FID, &Invalid);
  if (Invalid || !SEntry.isFile())
    return true;

  if (SEntry.getFile().getFileCharacteristic() != SrcMgr::C_User) {
    switch (IndexOpts.SystemSymbolFilter) {
    case IndexingOptions::SystemSymbolFilterKind::None:
      return true;
    case IndexingOptions::SystemSymbolFilterKind::DeclarationsOnly:
    case IndexingOptions::SystemSymbolFilterKind::All:
      break;
    }
  }

  SymbolRoleSet Roles = (unsigned)SymbolRole::Declaration;
  if (ImportD->isImplicit())
    Roles |= (unsigned)SymbolRole::Implicit;

  return DataConsumer.handleModuleOccurence(ImportD, Roles, FID, Offset);
}
Ejemplo n.º 29
0
/// Build scope information for a captured block literal variables.
void JumpScopeChecker::BuildScopeInformation(VarDecl *D,
                                             const BlockDecl *BDecl,
                                             unsigned &ParentScope) {
  // exclude captured __block variables; there's no destructor
  // associated with the block literal for them.
  if (D->hasAttr<BlocksAttr>())
    return;
  QualType T = D->getType();
  QualType::DestructionKind destructKind = T.isDestructedType();
  if (destructKind != QualType::DK_none) {
    std::pair<unsigned,unsigned> Diags;
    switch (destructKind) {
      case QualType::DK_cxx_destructor:
        Diags = ScopePair(diag::note_enters_block_captures_cxx_obj,
                          diag::note_exits_block_captures_cxx_obj);
        break;
      case QualType::DK_objc_strong_lifetime:
        Diags = ScopePair(diag::note_enters_block_captures_strong,
                          diag::note_exits_block_captures_strong);
        break;
      case QualType::DK_objc_weak_lifetime:
        Diags = ScopePair(diag::note_enters_block_captures_weak,
                          diag::note_exits_block_captures_weak);
        break;
      case QualType::DK_nontrivial_c_struct:
        Diags = ScopePair(diag::note_enters_block_captures_non_trivial_c_struct,
                          diag::note_exits_block_captures_non_trivial_c_struct);
        break;
      case QualType::DK_none:
        llvm_unreachable("non-lifetime captured variable");
    }
    SourceLocation Loc = D->getLocation();
    if (Loc.isInvalid())
      Loc = BDecl->getLocation();
    Scopes.push_back(GotoScope(ParentScope,
                               Diags.first, Diags.second, Loc));
    ParentScope = Scopes.size()-1;
  }
}
Ejemplo n.º 30
0
bool RewriteUtils::replaceRecordType(RecordTypeLoc &RTLoc,
                                     const std::string &Name)
{
  const IdentifierInfo *TypeId = RTLoc.getType().getBaseTypeIdentifier();
  SourceLocation LocStart = RTLoc.getLocStart();

  // Loc could be invalid, for example:
  // class AAA { };
  // class BBB:AAA {
  // public:
  //   BBB () { }
  // };
  // In Clang's internal representation, BBB's Ctor is BBB() : AAA() {}
  // The implicit AAA() will be visited here 
  // This is the only case where RTLoc is invalid, so the question is -
  // Is the guard below too strong? It is possible it could mask other 
  // potential bugs?
  if (LocStart.isInvalid())
    return true;

  return !(TheRewriter->ReplaceText(LocStart, TypeId->getLength(), Name));
}