ASTDiagnostic.cpp revision 79a9a3417929e340e84dcbc06ed9c3a277cad959
179a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor//===--- ASTDiagnostic.cpp - Diagnostic Printing Hooks for AST Nodes ------===// 279a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor// 379a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor// The LLVM Compiler Infrastructure 479a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor// 579a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor// This file is distributed under the University of Illinois Open Source 679a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor// License. See LICENSE.TXT for details. 779a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor// 879a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor//===----------------------------------------------------------------------===// 979a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor// 1079a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor// This file implements a diagnostic formatting hook for AST elements. 1179a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor// 1279a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor//===----------------------------------------------------------------------===// 1379a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor#include "clang/AST/ASTDiagnostic.h" 1479a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor 1579a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor#include "clang/AST/ASTContext.h" 1679a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor#include "clang/AST/DeclObjC.h" 1779a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor#include "clang/AST/Type.h" 1879a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor#include "llvm/Support/raw_ostream.h" 1979a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor 2079a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregorusing namespace clang; 2179a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor 2279a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor/// Determines whether we should have an a.k.a. clause when 2379a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor/// pretty-printing a type. There are three main criteria: 2479a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor/// 2579a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor/// 1) Some types provide very minimal sugar that doesn't impede the 2679a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor/// user's understanding --- for example, elaborated type 2779a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor/// specifiers. If this is all the sugar we see, we don't want an 2879a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor/// a.k.a. clause. 2979a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor/// 2) Some types are technically sugared but are much more familiar 3079a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor/// when seen in their sugared form --- for example, va_list, 3179a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor/// vector types, and the magic Objective C types. We don't 3279a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor/// want to desugar these, even if we do produce an a.k.a. clause. 3379a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor/// 3) Some types may have already been desugared previously in this diagnostic. 3479a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor/// if this is the case, doing another "aka" would just be clutter. 3579a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor/// 3679a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregorstatic bool ShouldAKA(ASTContext &Context, QualType QT, 3779a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor const Diagnostic::ArgumentValue *PrevArgs, 3879a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor unsigned NumPrevArgs, 3979a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor QualType &DesugaredQT) { 4079a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor QualType InputTy = QT; 4179a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor 4279a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor bool AKA = false; 4379a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor QualifierCollector Qc; 4479a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor 4579a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor while (true) { 4679a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor const Type *Ty = Qc.strip(QT); 4779a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor 4879a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor // Don't aka just because we saw an elaborated type... 4979a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor if (isa<ElaboratedType>(Ty)) { 5079a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor QT = cast<ElaboratedType>(Ty)->desugar(); 5179a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor continue; 5279a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor } 5379a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor 5479a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor // ...or a qualified name type... 5579a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor if (isa<QualifiedNameType>(Ty)) { 5679a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor QT = cast<QualifiedNameType>(Ty)->desugar(); 5779a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor continue; 5879a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor } 5979a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor 6079a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor // ...or a substituted template type parameter. 6179a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor if (isa<SubstTemplateTypeParmType>(Ty)) { 6279a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor QT = cast<SubstTemplateTypeParmType>(Ty)->desugar(); 6379a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor continue; 6479a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor } 6579a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor 6679a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor // Don't desugar template specializations. 6779a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor if (isa<TemplateSpecializationType>(Ty)) 6879a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor break; 6979a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor 7079a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor // Don't desugar magic Objective-C types. 7179a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor if (QualType(Ty,0) == Context.getObjCIdType() || 7279a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor QualType(Ty,0) == Context.getObjCClassType() || 7379a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor QualType(Ty,0) == Context.getObjCSelType() || 7479a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor QualType(Ty,0) == Context.getObjCProtoType()) 7579a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor break; 7679a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor 7779a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor // Don't desugar va_list. 7879a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor if (QualType(Ty,0) == Context.getBuiltinVaListType()) 7979a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor break; 8079a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor 8179a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor // Otherwise, do a single-step desugar. 8279a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor QualType Underlying; 8379a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor bool IsSugar = false; 8479a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor switch (Ty->getTypeClass()) { 8579a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor#define ABSTRACT_TYPE(Class, Base) 8679a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor#define TYPE(Class, Base) \ 8779a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregorcase Type::Class: { \ 8879a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregorconst Class##Type *CTy = cast<Class##Type>(Ty); \ 8979a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregorif (CTy->isSugared()) { \ 9079a9a3417929e340e84dcbc06ed9c3a277cad959Douglas GregorIsSugar = true; \ 9179a9a3417929e340e84dcbc06ed9c3a277cad959Douglas GregorUnderlying = CTy->desugar(); \ 9279a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor} \ 9379a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregorbreak; \ 9479a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor} 9579a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor#include "clang/AST/TypeNodes.def" 9679a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor } 9779a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor 9879a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor // If it wasn't sugared, we're done. 9979a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor if (!IsSugar) 10079a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor break; 10179a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor 10279a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor // If the desugared type is a vector type, we don't want to expand 10379a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor // it, it will turn into an attribute mess. People want their "vec4". 10479a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor if (isa<VectorType>(Underlying)) 10579a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor break; 10679a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor 10779a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor // Don't desugar through the primary typedef of an anonymous type. 10879a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor if (isa<TagType>(Underlying) && isa<TypedefType>(QT)) 10979a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor if (cast<TagType>(Underlying)->getDecl()->getTypedefForAnonDecl() == 11079a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor cast<TypedefType>(QT)->getDecl()) 11179a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor break; 11279a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor 11379a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor // Otherwise, we're tearing through something opaque; note that 11479a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor // we'll eventually need an a.k.a. clause and keep going. 11579a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor AKA = true; 11679a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor QT = Underlying; 11779a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor continue; 11879a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor } 11979a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor 12079a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor // If we never tore through opaque sugar, don't print aka. 12179a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor if (!AKA) return false; 12279a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor 12379a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor // If we did, check to see if we already desugared this type in this 12479a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor // diagnostic. If so, don't do it again. 12579a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor for (unsigned i = 0; i != NumPrevArgs; ++i) { 12679a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor // TODO: Handle ak_declcontext case. 12779a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor if (PrevArgs[i].first == Diagnostic::ak_qualtype) { 12879a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor void *Ptr = (void*)PrevArgs[i].second; 12979a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor QualType PrevTy(QualType::getFromOpaquePtr(Ptr)); 13079a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor if (PrevTy == InputTy) 13179a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor return false; 13279a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor } 13379a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor } 13479a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor 13579a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor DesugaredQT = Qc.apply(QT); 13679a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor return true; 13779a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor} 13879a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor 13979a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor/// \brief Convert the given type to a string suitable for printing as part of 14079a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor/// a diagnostic. 14179a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor/// 14279a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor/// \param Context the context in which the type was allocated 14379a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor/// \param Ty the type to print 14479a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregorstatic std::string 14579a9a3417929e340e84dcbc06ed9c3a277cad959Douglas GregorConvertTypeToDiagnosticString(ASTContext &Context, QualType Ty, 14679a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor const Diagnostic::ArgumentValue *PrevArgs, 14779a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor unsigned NumPrevArgs) { 14879a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor // FIXME: Playing with std::string is really slow. 14979a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor std::string S = Ty.getAsString(Context.PrintingPolicy); 15079a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor 15179a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor // Consider producing an a.k.a. clause if removing all the direct 15279a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor // sugar gives us something "significantly different". 15379a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor 15479a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor QualType DesugaredTy; 15579a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor if (ShouldAKA(Context, Ty, PrevArgs, NumPrevArgs, DesugaredTy)) { 15679a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor S = "'"+S+"' (aka '"; 15779a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor S += DesugaredTy.getAsString(Context.PrintingPolicy); 15879a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor S += "')"; 15979a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor return S; 16079a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor } 16179a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor 16279a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor S = "'" + S + "'"; 16379a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor return S; 16479a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor} 16579a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor 16679a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregorvoid clang::FormatASTNodeDiagnosticArgument(Diagnostic::ArgumentKind Kind, 16779a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor intptr_t Val, 16879a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor const char *Modifier, 16979a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor unsigned ModLen, 17079a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor const char *Argument, 17179a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor unsigned ArgLen, 17279a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor const Diagnostic::ArgumentValue *PrevArgs, 17379a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor unsigned NumPrevArgs, 17479a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor llvm::SmallVectorImpl<char> &Output, 17579a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor void *Cookie) { 17679a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor ASTContext &Context = *static_cast<ASTContext*>(Cookie); 17779a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor 17879a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor std::string S; 17979a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor bool NeedQuotes = true; 18079a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor 18179a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor switch (Kind) { 18279a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor default: assert(0 && "unknown ArgumentKind"); 18379a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor case Diagnostic::ak_qualtype: { 18479a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor assert(ModLen == 0 && ArgLen == 0 && 18579a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor "Invalid modifier for QualType argument"); 18679a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor 18779a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor QualType Ty(QualType::getFromOpaquePtr(reinterpret_cast<void*>(Val))); 18879a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor S = ConvertTypeToDiagnosticString(Context, Ty, PrevArgs, NumPrevArgs); 18979a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor NeedQuotes = false; 19079a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor break; 19179a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor } 19279a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor case Diagnostic::ak_declarationname: { 19379a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor DeclarationName N = DeclarationName::getFromOpaqueInteger(Val); 19479a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor S = N.getAsString(); 19579a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor 19679a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor if (ModLen == 9 && !memcmp(Modifier, "objcclass", 9) && ArgLen == 0) 19779a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor S = '+' + S; 19879a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor else if (ModLen == 12 && !memcmp(Modifier, "objcinstance", 12) 19979a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor && ArgLen==0) 20079a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor S = '-' + S; 20179a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor else 20279a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor assert(ModLen == 0 && ArgLen == 0 && 20379a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor "Invalid modifier for DeclarationName argument"); 20479a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor break; 20579a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor } 20679a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor case Diagnostic::ak_nameddecl: { 20779a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor bool Qualified; 20879a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor if (ModLen == 1 && Modifier[0] == 'q' && ArgLen == 0) 20979a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor Qualified = true; 21079a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor else { 21179a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor assert(ModLen == 0 && ArgLen == 0 && 21279a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor "Invalid modifier for NamedDecl* argument"); 21379a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor Qualified = false; 21479a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor } 21579a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor reinterpret_cast<NamedDecl*>(Val)-> 21679a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor getNameForDiagnostic(S, Context.PrintingPolicy, Qualified); 21779a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor break; 21879a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor } 21979a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor case Diagnostic::ak_nestednamespec: { 22079a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor llvm::raw_string_ostream OS(S); 22179a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor reinterpret_cast<NestedNameSpecifier*>(Val)->print(OS, 22279a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor Context.PrintingPolicy); 22379a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor NeedQuotes = false; 22479a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor break; 22579a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor } 22679a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor case Diagnostic::ak_declcontext: { 22779a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor DeclContext *DC = reinterpret_cast<DeclContext *> (Val); 22879a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor assert(DC && "Should never have a null declaration context"); 22979a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor 23079a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor if (DC->isTranslationUnit()) { 23179a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor // FIXME: Get these strings from some localized place 23279a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor if (Context.getLangOptions().CPlusPlus) 23379a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor S = "the global namespace"; 23479a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor else 23579a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor S = "the global scope"; 23679a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor } else if (TypeDecl *Type = dyn_cast<TypeDecl>(DC)) { 23779a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor S = ConvertTypeToDiagnosticString(Context, 23879a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor Context.getTypeDeclType(Type), 23979a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor PrevArgs, NumPrevArgs); 24079a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor } else { 24179a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor // FIXME: Get these strings from some localized place 24279a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor NamedDecl *ND = cast<NamedDecl>(DC); 24379a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor if (isa<NamespaceDecl>(ND)) 24479a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor S += "namespace "; 24579a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor else if (isa<ObjCMethodDecl>(ND)) 24679a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor S += "method "; 24779a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor else if (isa<FunctionDecl>(ND)) 24879a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor S += "function "; 24979a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor 25079a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor S += "'"; 25179a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor ND->getNameForDiagnostic(S, Context.PrintingPolicy, true); 25279a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor S += "'"; 25379a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor } 25479a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor NeedQuotes = false; 25579a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor break; 25679a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor } 25779a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor } 25879a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor 25979a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor if (NeedQuotes) 26079a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor Output.push_back('\''); 26179a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor 26279a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor Output.append(S.begin(), S.end()); 26379a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor 26479a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor if (NeedQuotes) 26579a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor Output.push_back('\''); 26679a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor} 267