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)); } }
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(); }
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); } }
raw_ostream &operator<<(raw_ostream &OS, DeclarationName N) { LangOptions LO; N.print(OS, PrintingPolicy(LO)); return OS; }
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"); }
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"); }