void UseUsingCheck::check(const MatchFinder::MatchResult &Result) {
  const auto *MatchedDecl = Result.Nodes.getNodeAs<TypedefDecl>("typedef");
  if (MatchedDecl->getLocation().isInvalid())
    return;

  auto &Context = *Result.Context;
  auto &SM = *Result.SourceManager;

  SourceLocation StartLoc = MatchedDecl->getBeginLoc();

  if (StartLoc.isMacroID() && IgnoreMacros)
    return;

  auto Diag =
      diag(StartLoc, "use 'using' instead of 'typedef'");

  // do not fix if there is macro or array
  if (MatchedDecl->getUnderlyingType()->isArrayType() || StartLoc.isMacroID())
    return;

  if (CheckRemoval(SM, StartLoc, Context)) {
    auto printPolicy = PrintingPolicy(getLangOpts());
    printPolicy.SuppressScope = true;
    printPolicy.ConstantArraySizeAsWritten = true;
    printPolicy.UseVoidForZeroParams = false;

    Diag << FixItHint::CreateReplacement(
        MatchedDecl->getSourceRange(),
        "using " + MatchedDecl->getNameAsString() + " = " +
            MatchedDecl->getUnderlyingType().getAsString(printPolicy));
  }
}
Beispiel #2
0
string VarCollector::GetStmtString(Stmt * S) {

    string SStr;
    llvm::raw_string_ostream Stream(SStr);

    CompilerInstance &CI = FullDirectives->GetCI(S->getLocStart());

    StmtPrinter P(Stream, 0, PrintingPolicy(CI.getLangOpts()), 0);
    P.Visit(const_cast<Stmt*>(cast<Stmt>(S)));

    return Stream.str();

}
string FakeDirectiveHandler::GetStmtString(Stmt * Current) {

    string SStr;
    llvm::raw_string_ostream S(SStr);

    CompilerInstance &CI = FullDirectives->GetCI(Current->getLocStart());

    NoEditStmtPrinter P(S, 0, PrintingPolicy(CI.getLangOpts()), 0);
    P.Visit(const_cast<Stmt*>(cast<Stmt>(Current)));

    return S.str();

}
Beispiel #4
0
static void printCXXConstructorDestructorName(QualType ClassType,
                                              raw_ostream &OS,
                                              const PrintingPolicy &Policy) {
  if (const RecordType *ClassRec = ClassType->getAs<RecordType>()) {
    OS << *ClassRec->getDecl();
    return;
  }
  if (!Policy.LangOpts.CPlusPlus) {
    // Passed policy is the default one from operator <<, use a C++ policy.
    LangOptions LO;
    LO.CPlusPlus = true;
    ClassType.print(OS, PrintingPolicy(LO));
  } else {
    ClassType.print(OS, Policy);
  }
}
Beispiel #5
0
raw_ostream &operator<<(raw_ostream &OS, DeclarationName N) {
  LangOptions LO;
  N.print(OS, PrintingPolicy(LO));
  return OS;
}
Beispiel #6
0
void DeclarationName::print(raw_ostream &OS, const PrintingPolicy &Policy) {
  DeclarationName &N = *this;
  switch (N.getNameKind()) {
  case DeclarationName::Identifier:
    if (const IdentifierInfo *II = N.getAsIdentifierInfo())
      OS << II->getName();
    return;

  case DeclarationName::ObjCZeroArgSelector:
  case DeclarationName::ObjCOneArgSelector:
  case DeclarationName::ObjCMultiArgSelector:
    N.getObjCSelector().print(OS);
    return;

  case DeclarationName::CXXConstructorName:
    return printCXXConstructorDestructorName(N.getCXXNameType(), OS, Policy);

  case DeclarationName::CXXDestructorName: {
    OS << '~';
    return printCXXConstructorDestructorName(N.getCXXNameType(), OS, Policy);
  }

  case DeclarationName::CXXOperatorName: {
    static const char* const OperatorNames[NUM_OVERLOADED_OPERATORS] = {
      nullptr,
#define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \
      Spelling,
#include "clang/Basic/OperatorKinds.def"
    };
    const char *OpName = OperatorNames[N.getCXXOverloadedOperator()];
    assert(OpName && "not an overloaded operator");

    OS << "operator";
    if (OpName[0] >= 'a' && OpName[0] <= 'z')
      OS << ' ';
    OS << OpName;
    return;
  }

  case DeclarationName::CXXLiteralOperatorName:
    OS << "operator\"\"" << N.getCXXLiteralIdentifier()->getName();
    return;

  case DeclarationName::CXXConversionFunctionName: {
    OS << "operator ";
    QualType Type = N.getCXXNameType();
    if (const RecordType *Rec = Type->getAs<RecordType>()) {
      OS << *Rec->getDecl();
      return;
    }
    if (!Policy.LangOpts.CPlusPlus) {
      // Passed policy is the default one from operator <<, use a C++ policy.
      LangOptions LO;
      LO.CPlusPlus = true;
      LO.Bool = true;
      Type.print(OS, PrintingPolicy(LO));
    } else {
      Type.print(OS, Policy);
    }
    return;
  }
  case DeclarationName::CXXUsingDirective:
    OS << "<using-directive>";
    return;
  }

  llvm_unreachable("Unexpected declaration name kind");
}
Beispiel #7
0
raw_ostream &operator<<(raw_ostream &OS, DeclarationName N) {
  switch (N.getNameKind()) {
  case DeclarationName::Identifier:
    if (const IdentifierInfo *II = N.getAsIdentifierInfo())
      OS << II->getName();
    return OS;

  case DeclarationName::ObjCZeroArgSelector:
  case DeclarationName::ObjCOneArgSelector:
  case DeclarationName::ObjCMultiArgSelector:
    N.getObjCSelector().print(OS);
    return OS;

  case DeclarationName::CXXConstructorName: {
    QualType ClassType = N.getCXXNameType();
    if (const RecordType *ClassRec = ClassType->getAs<RecordType>())
      return OS << *ClassRec->getDecl();
    LangOptions LO;
    LO.CPlusPlus = true;
    return OS << ClassType.getAsString(PrintingPolicy(LO));
  }

  case DeclarationName::CXXDestructorName: {
    OS << '~';
    QualType Type = N.getCXXNameType();
    if (const RecordType *Rec = Type->getAs<RecordType>())
      return OS << *Rec->getDecl();
    LangOptions LO;
    LO.CPlusPlus = true;
    return OS << Type.getAsString(PrintingPolicy(LO));
  }

  case DeclarationName::CXXOperatorName: {
    static const char* const OperatorNames[NUM_OVERLOADED_OPERATORS] = {
      nullptr,
#define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \
      Spelling,
#include "clang/Basic/OperatorKinds.def"
    };
    const char *OpName = OperatorNames[N.getCXXOverloadedOperator()];
    assert(OpName && "not an overloaded operator");

    OS << "operator";
    if (OpName[0] >= 'a' && OpName[0] <= 'z')
      OS << ' ';
    return OS << OpName;
  }

  case DeclarationName::CXXLiteralOperatorName:
    return OS << "operator\"\"" << N.getCXXLiteralIdentifier()->getName();

  case DeclarationName::CXXConversionFunctionName: {
    OS << "operator ";
    QualType Type = N.getCXXNameType();
    if (const RecordType *Rec = Type->getAs<RecordType>())
      return OS << *Rec->getDecl();
    LangOptions LO;
    LO.CPlusPlus = true;
    LO.Bool = true;
    return OS << Type.getAsString(PrintingPolicy(LO));
  }
  case DeclarationName::CXXUsingDirective:
    return OS << "<using-directive>";
  }

  llvm_unreachable("Unexpected declaration name kind");
}