ASTDiagnostic.cpp revision 0673cb30340aadaede7b795c763b00f6b64e611c
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 221733bc3747f242ddaea5b953d27f514253843e31Chandler Carruth// Returns a desugared version of the QualType, and marks ShouldAKA as true 231733bc3747f242ddaea5b953d27f514253843e31Chandler Carruth// whenever we remove significant sugar from the type. 241733bc3747f242ddaea5b953d27f514253843e31Chandler Carruthstatic QualType Desugar(ASTContext &Context, QualType QT, bool &ShouldAKA) { 251733bc3747f242ddaea5b953d27f514253843e31Chandler Carruth QualifierCollector QC; 261733bc3747f242ddaea5b953d27f514253843e31Chandler Carruth 2779a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor while (true) { 281733bc3747f242ddaea5b953d27f514253843e31Chandler Carruth const Type *Ty = QC.strip(QT); 291733bc3747f242ddaea5b953d27f514253843e31Chandler Carruth 3079a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor // Don't aka just because we saw an elaborated type... 3134b41d939a1328f484511c6002ba2456db879a29Richard Smith if (const ElaboratedType *ET = dyn_cast<ElaboratedType>(Ty)) { 3234b41d939a1328f484511c6002ba2456db879a29Richard Smith QT = ET->desugar(); 3379a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor continue; 3479a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor } 35075f8f1b6bed4d1b224c74f87508534cc6392ce6Abramo Bagnara // ... or a paren type ... 3634b41d939a1328f484511c6002ba2456db879a29Richard Smith if (const ParenType *PT = dyn_cast<ParenType>(Ty)) { 3734b41d939a1328f484511c6002ba2456db879a29Richard Smith QT = PT->desugar(); 38075f8f1b6bed4d1b224c74f87508534cc6392ce6Abramo Bagnara continue; 39075f8f1b6bed4d1b224c74f87508534cc6392ce6Abramo Bagnara } 4034b41d939a1328f484511c6002ba2456db879a29Richard Smith // ...or a substituted template type parameter ... 4134b41d939a1328f484511c6002ba2456db879a29Richard Smith if (const SubstTemplateTypeParmType *ST = 4234b41d939a1328f484511c6002ba2456db879a29Richard Smith dyn_cast<SubstTemplateTypeParmType>(Ty)) { 4334b41d939a1328f484511c6002ba2456db879a29Richard Smith QT = ST->desugar(); 4434b41d939a1328f484511c6002ba2456db879a29Richard Smith continue; 4534b41d939a1328f484511c6002ba2456db879a29Richard Smith } 4614aa2175416f79ef17811282afbf425f87d54ebfJohn McCall // ...or an attributed type... 4714aa2175416f79ef17811282afbf425f87d54ebfJohn McCall if (const AttributedType *AT = dyn_cast<AttributedType>(Ty)) { 4814aa2175416f79ef17811282afbf425f87d54ebfJohn McCall QT = AT->desugar(); 4914aa2175416f79ef17811282afbf425f87d54ebfJohn McCall continue; 5014aa2175416f79ef17811282afbf425f87d54ebfJohn McCall } 5134b41d939a1328f484511c6002ba2456db879a29Richard Smith // ... or an auto type. 5234b41d939a1328f484511c6002ba2456db879a29Richard Smith if (const AutoType *AT = dyn_cast<AutoType>(Ty)) { 5334b41d939a1328f484511c6002ba2456db879a29Richard Smith if (!AT->isSugared()) 5434b41d939a1328f484511c6002ba2456db879a29Richard Smith break; 5534b41d939a1328f484511c6002ba2456db879a29Richard Smith QT = AT->desugar(); 5679a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor continue; 5779a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor } 581733bc3747f242ddaea5b953d27f514253843e31Chandler Carruth 593e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith // Don't desugar template specializations, unless it's an alias template. 603e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith if (const TemplateSpecializationType *TST 613e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith = dyn_cast<TemplateSpecializationType>(Ty)) 623e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith if (!TST->isTypeAlias()) 633e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith break; 641733bc3747f242ddaea5b953d27f514253843e31Chandler Carruth 6579a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor // Don't desugar magic Objective-C types. 6679a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor if (QualType(Ty,0) == Context.getObjCIdType() || 6779a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor QualType(Ty,0) == Context.getObjCClassType() || 6879a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor QualType(Ty,0) == Context.getObjCSelType() || 6979a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor QualType(Ty,0) == Context.getObjCProtoType()) 7079a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor break; 711733bc3747f242ddaea5b953d27f514253843e31Chandler Carruth 7279a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor // Don't desugar va_list. 7379a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor if (QualType(Ty,0) == Context.getBuiltinVaListType()) 7479a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor break; 751733bc3747f242ddaea5b953d27f514253843e31Chandler Carruth 7679a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor // Otherwise, do a single-step desugar. 7779a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor QualType Underlying; 7879a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor bool IsSugar = false; 7979a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor switch (Ty->getTypeClass()) { 8079a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor#define ABSTRACT_TYPE(Class, Base) 8179a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor#define TYPE(Class, Base) \ 8279a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregorcase Type::Class: { \ 8379a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregorconst Class##Type *CTy = cast<Class##Type>(Ty); \ 8479a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregorif (CTy->isSugared()) { \ 8579a9a3417929e340e84dcbc06ed9c3a277cad959Douglas GregorIsSugar = true; \ 8679a9a3417929e340e84dcbc06ed9c3a277cad959Douglas GregorUnderlying = CTy->desugar(); \ 8779a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor} \ 8879a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregorbreak; \ 8979a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor} 9079a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor#include "clang/AST/TypeNodes.def" 9179a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor } 921733bc3747f242ddaea5b953d27f514253843e31Chandler Carruth 9379a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor // If it wasn't sugared, we're done. 9479a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor if (!IsSugar) 9579a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor break; 961733bc3747f242ddaea5b953d27f514253843e31Chandler Carruth 9779a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor // If the desugared type is a vector type, we don't want to expand 9879a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor // it, it will turn into an attribute mess. People want their "vec4". 9979a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor if (isa<VectorType>(Underlying)) 10079a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor break; 1011733bc3747f242ddaea5b953d27f514253843e31Chandler Carruth 10279a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor // Don't desugar through the primary typedef of an anonymous type. 103c3f8c0731ef59ba79753f89f1c108b8134f6ae83Chris Lattner if (const TagType *UTT = Underlying->getAs<TagType>()) 104c3f8c0731ef59ba79753f89f1c108b8134f6ae83Chris Lattner if (const TypedefType *QTT = dyn_cast<TypedefType>(QT)) 105162e1c1b487352434552147967c3dd296ebee2f7Richard Smith if (UTT->getDecl()->getTypedefNameForAnonDecl() == QTT->getDecl()) 106c3f8c0731ef59ba79753f89f1c108b8134f6ae83Chris Lattner break; 1071733bc3747f242ddaea5b953d27f514253843e31Chandler Carruth 1081733bc3747f242ddaea5b953d27f514253843e31Chandler Carruth // Record that we actually looked through an opaque type here. 1091733bc3747f242ddaea5b953d27f514253843e31Chandler Carruth ShouldAKA = true; 11079a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor QT = Underlying; 11179a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor } 1121733bc3747f242ddaea5b953d27f514253843e31Chandler Carruth 1131733bc3747f242ddaea5b953d27f514253843e31Chandler Carruth // If we have a pointer-like type, desugar the pointee as well. 1141733bc3747f242ddaea5b953d27f514253843e31Chandler Carruth // FIXME: Handle other pointer-like types. 1151733bc3747f242ddaea5b953d27f514253843e31Chandler Carruth if (const PointerType *Ty = QT->getAs<PointerType>()) { 116c3f8c0731ef59ba79753f89f1c108b8134f6ae83Chris Lattner QT = Context.getPointerType(Desugar(Context, Ty->getPointeeType(), 117c3f8c0731ef59ba79753f89f1c108b8134f6ae83Chris Lattner ShouldAKA)); 1181733bc3747f242ddaea5b953d27f514253843e31Chandler Carruth } else if (const LValueReferenceType *Ty = QT->getAs<LValueReferenceType>()) { 119c3f8c0731ef59ba79753f89f1c108b8134f6ae83Chris Lattner QT = Context.getLValueReferenceType(Desugar(Context, Ty->getPointeeType(), 120c3f8c0731ef59ba79753f89f1c108b8134f6ae83Chris Lattner ShouldAKA)); 12169d831645f429d3b806d2ae220aee45ca44f8c6cDouglas Gregor } else if (const RValueReferenceType *Ty = QT->getAs<RValueReferenceType>()) { 12269d831645f429d3b806d2ae220aee45ca44f8c6cDouglas Gregor QT = Context.getRValueReferenceType(Desugar(Context, Ty->getPointeeType(), 12369d831645f429d3b806d2ae220aee45ca44f8c6cDouglas Gregor ShouldAKA)); 12479a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor } 1251733bc3747f242ddaea5b953d27f514253843e31Chandler Carruth 12649f4e1cbd839da27ff4814b4ea6d85a79f786cbdJohn McCall return QC.apply(Context, QT); 12779a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor} 12879a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor 12979a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor/// \brief Convert the given type to a string suitable for printing as part of 1301733bc3747f242ddaea5b953d27f514253843e31Chandler Carruth/// a diagnostic. 1311733bc3747f242ddaea5b953d27f514253843e31Chandler Carruth/// 1320673cb30340aadaede7b795c763b00f6b64e611cChandler Carruth/// There are four main criteria when determining whether we should have an 1331733bc3747f242ddaea5b953d27f514253843e31Chandler Carruth/// a.k.a. clause when pretty-printing a type: 1341733bc3747f242ddaea5b953d27f514253843e31Chandler Carruth/// 1351733bc3747f242ddaea5b953d27f514253843e31Chandler Carruth/// 1) Some types provide very minimal sugar that doesn't impede the 1361733bc3747f242ddaea5b953d27f514253843e31Chandler Carruth/// user's understanding --- for example, elaborated type 1371733bc3747f242ddaea5b953d27f514253843e31Chandler Carruth/// specifiers. If this is all the sugar we see, we don't want an 1381733bc3747f242ddaea5b953d27f514253843e31Chandler Carruth/// a.k.a. clause. 1391733bc3747f242ddaea5b953d27f514253843e31Chandler Carruth/// 2) Some types are technically sugared but are much more familiar 1401733bc3747f242ddaea5b953d27f514253843e31Chandler Carruth/// when seen in their sugared form --- for example, va_list, 1411733bc3747f242ddaea5b953d27f514253843e31Chandler Carruth/// vector types, and the magic Objective C types. We don't 1421733bc3747f242ddaea5b953d27f514253843e31Chandler Carruth/// want to desugar these, even if we do produce an a.k.a. clause. 1431733bc3747f242ddaea5b953d27f514253843e31Chandler Carruth/// 3) Some types may have already been desugared previously in this diagnostic. 1441733bc3747f242ddaea5b953d27f514253843e31Chandler Carruth/// if this is the case, doing another "aka" would just be clutter. 1450673cb30340aadaede7b795c763b00f6b64e611cChandler Carruth/// 4) Two different types within the same diagnostic have the same output 1460673cb30340aadaede7b795c763b00f6b64e611cChandler Carruth/// string. In this case, force an a.k.a with the desugared type when 1470673cb30340aadaede7b795c763b00f6b64e611cChandler Carruth/// doing so will provide additional information. 14879a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor/// 14979a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor/// \param Context the context in which the type was allocated 15079a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor/// \param Ty the type to print 1510673cb30340aadaede7b795c763b00f6b64e611cChandler Carruth/// \param QualTypeVals pointer values to QualTypes which are used in the 1520673cb30340aadaede7b795c763b00f6b64e611cChandler Carruth/// diagnostic message 15379a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregorstatic std::string 15479a9a3417929e340e84dcbc06ed9c3a277cad959Douglas GregorConvertTypeToDiagnosticString(ASTContext &Context, QualType Ty, 15579a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor const Diagnostic::ArgumentValue *PrevArgs, 1560673cb30340aadaede7b795c763b00f6b64e611cChandler Carruth unsigned NumPrevArgs, 1570673cb30340aadaede7b795c763b00f6b64e611cChandler Carruth llvm::SmallVectorImpl<intptr_t> &QualTypeVals) { 15879a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor // FIXME: Playing with std::string is really slow. 1590673cb30340aadaede7b795c763b00f6b64e611cChandler Carruth bool ForceAKA = false; 1600673cb30340aadaede7b795c763b00f6b64e611cChandler Carruth QualType CanTy = Ty.getCanonicalType(); 16179a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor std::string S = Ty.getAsString(Context.PrintingPolicy); 1620673cb30340aadaede7b795c763b00f6b64e611cChandler Carruth std::string CanS = CanTy.getAsString(Context.PrintingPolicy); 1630673cb30340aadaede7b795c763b00f6b64e611cChandler Carruth 1640673cb30340aadaede7b795c763b00f6b64e611cChandler Carruth for (llvm::SmallVectorImpl<intptr_t>::iterator I = QualTypeVals.begin(), 1650673cb30340aadaede7b795c763b00f6b64e611cChandler Carruth E = QualTypeVals.end(); I != E; ++I) { 1660673cb30340aadaede7b795c763b00f6b64e611cChandler Carruth QualType CompareTy = 1670673cb30340aadaede7b795c763b00f6b64e611cChandler Carruth QualType::getFromOpaquePtr(reinterpret_cast<void*>(*I)); 1680673cb30340aadaede7b795c763b00f6b64e611cChandler Carruth if (CompareTy == Ty) 1690673cb30340aadaede7b795c763b00f6b64e611cChandler Carruth continue; // Same types 1700673cb30340aadaede7b795c763b00f6b64e611cChandler Carruth QualType CompareCanTy = CompareTy.getCanonicalType(); 1710673cb30340aadaede7b795c763b00f6b64e611cChandler Carruth if (CompareCanTy == CanTy) 1720673cb30340aadaede7b795c763b00f6b64e611cChandler Carruth continue; // Same canonical types 1730673cb30340aadaede7b795c763b00f6b64e611cChandler Carruth std::string CompareS = CompareTy.getAsString(Context.PrintingPolicy); 1740673cb30340aadaede7b795c763b00f6b64e611cChandler Carruth if (CompareS != S) 1750673cb30340aadaede7b795c763b00f6b64e611cChandler Carruth continue; // Original strings are different 1760673cb30340aadaede7b795c763b00f6b64e611cChandler Carruth std::string CompareCanS = CompareCanTy.getAsString(Context.PrintingPolicy); 1770673cb30340aadaede7b795c763b00f6b64e611cChandler Carruth if (CompareCanS == CanS) 1780673cb30340aadaede7b795c763b00f6b64e611cChandler Carruth continue; // No new info from canonical type 1790673cb30340aadaede7b795c763b00f6b64e611cChandler Carruth 1800673cb30340aadaede7b795c763b00f6b64e611cChandler Carruth ForceAKA = true; 1810673cb30340aadaede7b795c763b00f6b64e611cChandler Carruth break; 1820673cb30340aadaede7b795c763b00f6b64e611cChandler Carruth } 1831733bc3747f242ddaea5b953d27f514253843e31Chandler Carruth 1841733bc3747f242ddaea5b953d27f514253843e31Chandler Carruth // Check to see if we already desugared this type in this 1851733bc3747f242ddaea5b953d27f514253843e31Chandler Carruth // diagnostic. If so, don't do it again. 1861733bc3747f242ddaea5b953d27f514253843e31Chandler Carruth bool Repeated = false; 1871733bc3747f242ddaea5b953d27f514253843e31Chandler Carruth for (unsigned i = 0; i != NumPrevArgs; ++i) { 1881733bc3747f242ddaea5b953d27f514253843e31Chandler Carruth // TODO: Handle ak_declcontext case. 1891733bc3747f242ddaea5b953d27f514253843e31Chandler Carruth if (PrevArgs[i].first == Diagnostic::ak_qualtype) { 1901733bc3747f242ddaea5b953d27f514253843e31Chandler Carruth void *Ptr = (void*)PrevArgs[i].second; 1911733bc3747f242ddaea5b953d27f514253843e31Chandler Carruth QualType PrevTy(QualType::getFromOpaquePtr(Ptr)); 1921733bc3747f242ddaea5b953d27f514253843e31Chandler Carruth if (PrevTy == Ty) { 1931733bc3747f242ddaea5b953d27f514253843e31Chandler Carruth Repeated = true; 1941733bc3747f242ddaea5b953d27f514253843e31Chandler Carruth break; 1951733bc3747f242ddaea5b953d27f514253843e31Chandler Carruth } 1961733bc3747f242ddaea5b953d27f514253843e31Chandler Carruth } 1971733bc3747f242ddaea5b953d27f514253843e31Chandler Carruth } 1981733bc3747f242ddaea5b953d27f514253843e31Chandler Carruth 19979a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor // Consider producing an a.k.a. clause if removing all the direct 20079a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor // sugar gives us something "significantly different". 2011733bc3747f242ddaea5b953d27f514253843e31Chandler Carruth if (!Repeated) { 2021733bc3747f242ddaea5b953d27f514253843e31Chandler Carruth bool ShouldAKA = false; 2031733bc3747f242ddaea5b953d27f514253843e31Chandler Carruth QualType DesugaredTy = Desugar(Context, Ty, ShouldAKA); 2040673cb30340aadaede7b795c763b00f6b64e611cChandler Carruth if (ShouldAKA || ForceAKA) { 2050673cb30340aadaede7b795c763b00f6b64e611cChandler Carruth if (DesugaredTy == Ty) { 2060673cb30340aadaede7b795c763b00f6b64e611cChandler Carruth DesugaredTy = Ty.getCanonicalType(); 2070673cb30340aadaede7b795c763b00f6b64e611cChandler Carruth } 2080673cb30340aadaede7b795c763b00f6b64e611cChandler Carruth std::string akaStr = DesugaredTy.getAsString(Context.PrintingPolicy); 2090673cb30340aadaede7b795c763b00f6b64e611cChandler Carruth if (akaStr != S) { 2100673cb30340aadaede7b795c763b00f6b64e611cChandler Carruth S = "'" + S + "' (aka '" + akaStr + "')"; 2110673cb30340aadaede7b795c763b00f6b64e611cChandler Carruth return S; 2120673cb30340aadaede7b795c763b00f6b64e611cChandler Carruth } 2131733bc3747f242ddaea5b953d27f514253843e31Chandler Carruth } 21479a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor } 2151733bc3747f242ddaea5b953d27f514253843e31Chandler Carruth 21679a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor S = "'" + S + "'"; 21779a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor return S; 21879a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor} 21979a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor 2200673cb30340aadaede7b795c763b00f6b64e611cChandler Carruthvoid clang::FormatASTNodeDiagnosticArgument( 2210673cb30340aadaede7b795c763b00f6b64e611cChandler Carruth Diagnostic::ArgumentKind Kind, 2220673cb30340aadaede7b795c763b00f6b64e611cChandler Carruth intptr_t Val, 2230673cb30340aadaede7b795c763b00f6b64e611cChandler Carruth const char *Modifier, 2240673cb30340aadaede7b795c763b00f6b64e611cChandler Carruth unsigned ModLen, 2250673cb30340aadaede7b795c763b00f6b64e611cChandler Carruth const char *Argument, 2260673cb30340aadaede7b795c763b00f6b64e611cChandler Carruth unsigned ArgLen, 2270673cb30340aadaede7b795c763b00f6b64e611cChandler Carruth const Diagnostic::ArgumentValue *PrevArgs, 2280673cb30340aadaede7b795c763b00f6b64e611cChandler Carruth unsigned NumPrevArgs, 2290673cb30340aadaede7b795c763b00f6b64e611cChandler Carruth llvm::SmallVectorImpl<char> &Output, 2300673cb30340aadaede7b795c763b00f6b64e611cChandler Carruth void *Cookie, 2310673cb30340aadaede7b795c763b00f6b64e611cChandler Carruth llvm::SmallVectorImpl<intptr_t> &QualTypeVals) { 23279a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor ASTContext &Context = *static_cast<ASTContext*>(Cookie); 23379a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor 23479a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor std::string S; 23579a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor bool NeedQuotes = true; 23679a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor 23779a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor switch (Kind) { 23879a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor default: assert(0 && "unknown ArgumentKind"); 23979a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor case Diagnostic::ak_qualtype: { 24079a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor assert(ModLen == 0 && ArgLen == 0 && 24179a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor "Invalid modifier for QualType argument"); 24279a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor 24379a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor QualType Ty(QualType::getFromOpaquePtr(reinterpret_cast<void*>(Val))); 2440673cb30340aadaede7b795c763b00f6b64e611cChandler Carruth S = ConvertTypeToDiagnosticString(Context, Ty, PrevArgs, NumPrevArgs, 2450673cb30340aadaede7b795c763b00f6b64e611cChandler Carruth QualTypeVals); 24679a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor NeedQuotes = false; 24779a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor break; 24879a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor } 24979a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor case Diagnostic::ak_declarationname: { 25079a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor DeclarationName N = DeclarationName::getFromOpaqueInteger(Val); 25179a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor S = N.getAsString(); 25279a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor 25379a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor if (ModLen == 9 && !memcmp(Modifier, "objcclass", 9) && ArgLen == 0) 25479a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor S = '+' + S; 25579a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor else if (ModLen == 12 && !memcmp(Modifier, "objcinstance", 12) 25679a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor && ArgLen==0) 25779a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor S = '-' + S; 25879a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor else 25979a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor assert(ModLen == 0 && ArgLen == 0 && 26079a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor "Invalid modifier for DeclarationName argument"); 26179a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor break; 26279a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor } 26379a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor case Diagnostic::ak_nameddecl: { 26479a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor bool Qualified; 26579a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor if (ModLen == 1 && Modifier[0] == 'q' && ArgLen == 0) 26679a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor Qualified = true; 26779a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor else { 26879a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor assert(ModLen == 0 && ArgLen == 0 && 26979a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor "Invalid modifier for NamedDecl* argument"); 27079a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor Qualified = false; 27179a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor } 27279a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor reinterpret_cast<NamedDecl*>(Val)-> 27379a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor getNameForDiagnostic(S, Context.PrintingPolicy, Qualified); 27479a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor break; 27579a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor } 27679a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor case Diagnostic::ak_nestednamespec: { 27779a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor llvm::raw_string_ostream OS(S); 27879a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor reinterpret_cast<NestedNameSpecifier*>(Val)->print(OS, 27979a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor Context.PrintingPolicy); 28079a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor NeedQuotes = false; 28179a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor break; 28279a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor } 28379a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor case Diagnostic::ak_declcontext: { 28479a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor DeclContext *DC = reinterpret_cast<DeclContext *> (Val); 28579a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor assert(DC && "Should never have a null declaration context"); 28679a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor 28779a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor if (DC->isTranslationUnit()) { 28879a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor // FIXME: Get these strings from some localized place 28979a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor if (Context.getLangOptions().CPlusPlus) 29079a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor S = "the global namespace"; 29179a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor else 29279a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor S = "the global scope"; 29379a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor } else if (TypeDecl *Type = dyn_cast<TypeDecl>(DC)) { 29479a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor S = ConvertTypeToDiagnosticString(Context, 29579a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor Context.getTypeDeclType(Type), 2960673cb30340aadaede7b795c763b00f6b64e611cChandler Carruth PrevArgs, NumPrevArgs, QualTypeVals); 29779a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor } else { 29879a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor // FIXME: Get these strings from some localized place 29979a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor NamedDecl *ND = cast<NamedDecl>(DC); 30079a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor if (isa<NamespaceDecl>(ND)) 30179a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor S += "namespace "; 30279a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor else if (isa<ObjCMethodDecl>(ND)) 30379a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor S += "method "; 30479a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor else if (isa<FunctionDecl>(ND)) 30579a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor S += "function "; 30679a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor 30779a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor S += "'"; 30879a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor ND->getNameForDiagnostic(S, Context.PrintingPolicy, true); 30979a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor S += "'"; 31079a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor } 31179a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor NeedQuotes = false; 31279a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor break; 31379a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor } 31479a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor } 31579a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor 31679a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor if (NeedQuotes) 31779a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor Output.push_back('\''); 31879a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor 31979a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor Output.append(S.begin(), S.end()); 32079a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor 32179a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor if (NeedQuotes) 32279a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor Output.push_back('\''); 32379a9a3417929e340e84dcbc06ed9c3a277cad959Douglas Gregor} 324