1f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot//===--- PartialDiagnostic.h - Diagnostic "closures" ------------*- C++ -*-===// 2f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot// 3f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot// The LLVM Compiler Infrastructure 4f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot// 5f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot// This file is distributed under the University of Illinois Open Source 6f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot// License. See LICENSE.TXT for details. 7f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot// 8f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot//===----------------------------------------------------------------------===// 9f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// 10f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// \file 11f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// \brief Implements a partial diagnostic that can be emitted anwyhere 12f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// in a DiagnosticBuilder stream. 13f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// 14f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot//===----------------------------------------------------------------------===// 15f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 16f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot#ifndef LLVM_CLANG_BASIC_PARTIALDIAGNOSTIC_H 17f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot#define LLVM_CLANG_BASIC_PARTIALDIAGNOSTIC_H 18f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 19f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot#include "clang/Basic/Diagnostic.h" 20f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot#include "clang/Basic/SourceLocation.h" 21f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot#include "llvm/ADT/STLExtras.h" 22f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot#include "llvm/Support/Compiler.h" 23f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot#include "llvm/Support/DataTypes.h" 24f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot#include <cassert> 25f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 26f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotnamespace clang { 27f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 28f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotclass PartialDiagnostic { 29f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotpublic: 30f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot enum { 31f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot // The MaxArguments and MaxFixItHints member enum values from 32f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot // DiagnosticsEngine are private but DiagnosticsEngine declares 33f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot // PartialDiagnostic a friend. These enum values are redeclared 34f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot // here so that the nested Storage class below can access them. 35f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot MaxArguments = DiagnosticsEngine::MaxArguments 36f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot }; 37f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 38f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot struct Storage { 39f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot Storage() : NumDiagArgs(0) { } 40f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 41f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot enum { 42f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// \brief The maximum number of arguments we can hold. We 43f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// currently only support up to 10 arguments (%0-%9). 44f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// 45f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// A single diagnostic with more than that almost certainly has to 46f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// be simplified anyway. 47f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot MaxArguments = PartialDiagnostic::MaxArguments 48f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot }; 49f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 50f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// \brief The number of entries in Arguments. 51f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot unsigned char NumDiagArgs; 52f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 53f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// \brief Specifies for each argument whether it is in DiagArgumentsStr 54f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// or in DiagArguments. 55f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot unsigned char DiagArgumentsKind[MaxArguments]; 56f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 57f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// \brief The values for the various substitution positions. 58f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// 59f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// This is used when the argument is not an std::string. The specific value 60f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// is mangled into an intptr_t and the interpretation depends on exactly 61f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// what sort of argument kind it is. 62f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot intptr_t DiagArgumentsVal[MaxArguments]; 63f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 64f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// \brief The values for the various substitution positions that have 65f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// string arguments. 66f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot std::string DiagArgumentsStr[MaxArguments]; 67f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 68f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// \brief The list of ranges added to this diagnostic. 69f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot SmallVector<CharSourceRange, 8> DiagRanges; 70f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 71f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// \brief If valid, provides a hint with some code to insert, remove, or 72f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// modify at a particular position. 73f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot SmallVector<FixItHint, 6> FixItHints; 74f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot }; 75f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 76f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// \brief An allocator for Storage objects, which uses a small cache to 77f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// objects, used to reduce malloc()/free() traffic for partial diagnostics. 78f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot class StorageAllocator { 79f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot static const unsigned NumCached = 16; 80f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot Storage Cached[NumCached]; 81f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot Storage *FreeList[NumCached]; 82f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot unsigned NumFreeListEntries; 83f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 84f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot public: 85f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot StorageAllocator(); 86f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot ~StorageAllocator(); 87f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 88f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// \brief Allocate new storage. 89f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot Storage *Allocate() { 90f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot if (NumFreeListEntries == 0) 91f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot return new Storage; 92f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 93f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot Storage *Result = FreeList[--NumFreeListEntries]; 94f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot Result->NumDiagArgs = 0; 95f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot Result->DiagRanges.clear(); 96f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot Result->FixItHints.clear(); 97f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot return Result; 98f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot } 99f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 100f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// \brief Free the given storage object. 101f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot void Deallocate(Storage *S) { 102f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot if (S >= Cached && S <= Cached + NumCached) { 103f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot FreeList[NumFreeListEntries++] = S; 104f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot return; 105f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot } 106f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 107f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot delete S; 108f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot } 109f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot }; 110f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 111f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotprivate: 112f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot // NOTE: Sema assumes that PartialDiagnostic is location-invariant 113f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot // in the sense that its bits can be safely memcpy'ed and destructed 114f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot // in the new location. 115f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 116f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// \brief The diagnostic ID. 117f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot mutable unsigned DiagID; 118f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 119f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// \brief Storage for args and ranges. 120f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot mutable Storage *DiagStorage; 121f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 122f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// \brief Allocator used to allocate storage for this diagnostic. 123f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot StorageAllocator *Allocator; 124f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 125f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// \brief Retrieve storage for this particular diagnostic. 126f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot Storage *getStorage() const { 127f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot if (DiagStorage) 128f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot return DiagStorage; 129f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 130f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot if (Allocator) 131f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot DiagStorage = Allocator->Allocate(); 132f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot else { 133f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot assert(Allocator != reinterpret_cast<StorageAllocator *>(~uintptr_t(0))); 134f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot DiagStorage = new Storage; 135f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot } 136f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot return DiagStorage; 137f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot } 138f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 139f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot void freeStorage() { 140f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot if (!DiagStorage) 141f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot return; 142f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 143f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot // The hot path for PartialDiagnostic is when we just used it to wrap an ID 144f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot // (typically so we have the flexibility of passing a more complex 145f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot // diagnostic into the callee, but that does not commonly occur). 146f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot // 147f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot // Split this out into a slow function for silly compilers (*cough*) which 148f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot // can't do decent partial inlining. 149f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot freeStorageSlow(); 150f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot } 151f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 152f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot void freeStorageSlow() { 153f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot if (Allocator) 154f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot Allocator->Deallocate(DiagStorage); 155f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot else if (Allocator != reinterpret_cast<StorageAllocator *>(~uintptr_t(0))) 156f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot delete DiagStorage; 157f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot DiagStorage = nullptr; 158f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot } 159f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 160f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot void AddSourceRange(const CharSourceRange &R) const { 161f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot if (!DiagStorage) 162f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot DiagStorage = getStorage(); 163f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 164f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot DiagStorage->DiagRanges.push_back(R); 165f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot } 166f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 167f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot void AddFixItHint(const FixItHint &Hint) const { 168f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot if (Hint.isNull()) 169f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot return; 170f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 171f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot if (!DiagStorage) 172f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot DiagStorage = getStorage(); 173f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 174f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot DiagStorage->FixItHints.push_back(Hint); 175f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot } 176f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 177f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotpublic: 178f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot struct NullDiagnostic {}; 179f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// \brief Create a null partial diagnostic, which cannot carry a payload, 180f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// and only exists to be swapped with a real partial diagnostic. 181f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot PartialDiagnostic(NullDiagnostic) 182f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot : DiagID(0), DiagStorage(nullptr), Allocator(nullptr) { } 183f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 184f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot PartialDiagnostic(unsigned DiagID, StorageAllocator &Allocator) 185f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot : DiagID(DiagID), DiagStorage(nullptr), Allocator(&Allocator) { } 186f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 187f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot PartialDiagnostic(const PartialDiagnostic &Other) 188f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot : DiagID(Other.DiagID), DiagStorage(nullptr), Allocator(Other.Allocator) 189f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot { 190f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot if (Other.DiagStorage) { 191f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot DiagStorage = getStorage(); 192f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot *DiagStorage = *Other.DiagStorage; 193f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot } 194f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot } 195f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 196f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot PartialDiagnostic(PartialDiagnostic &&Other) 197f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot : DiagID(Other.DiagID), DiagStorage(Other.DiagStorage), 198f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot Allocator(Other.Allocator) { 199f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot Other.DiagStorage = nullptr; 200f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot } 201f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 202f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot PartialDiagnostic(const PartialDiagnostic &Other, Storage *DiagStorage) 203f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot : DiagID(Other.DiagID), DiagStorage(DiagStorage), 204f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot Allocator(reinterpret_cast<StorageAllocator *>(~uintptr_t(0))) 205f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot { 206f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot if (Other.DiagStorage) 207f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot *this->DiagStorage = *Other.DiagStorage; 208f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot } 209f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 210f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot PartialDiagnostic(const Diagnostic &Other, StorageAllocator &Allocator) 211f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot : DiagID(Other.getID()), DiagStorage(nullptr), Allocator(&Allocator) 212f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot { 213f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot // Copy arguments. 214f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot for (unsigned I = 0, N = Other.getNumArgs(); I != N; ++I) { 215f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot if (Other.getArgKind(I) == DiagnosticsEngine::ak_std_string) 216f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot AddString(Other.getArgStdStr(I)); 217f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot else 218f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot AddTaggedVal(Other.getRawArg(I), Other.getArgKind(I)); 219f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot } 220f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 221f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot // Copy source ranges. 222f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot for (unsigned I = 0, N = Other.getNumRanges(); I != N; ++I) 223f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot AddSourceRange(Other.getRange(I)); 224f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 225f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot // Copy fix-its. 226f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot for (unsigned I = 0, N = Other.getNumFixItHints(); I != N; ++I) 227f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot AddFixItHint(Other.getFixItHint(I)); 228f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot } 229f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 230f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot PartialDiagnostic &operator=(const PartialDiagnostic &Other) { 231f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot DiagID = Other.DiagID; 232f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot if (Other.DiagStorage) { 233f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot if (!DiagStorage) 234f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot DiagStorage = getStorage(); 235f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 236f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot *DiagStorage = *Other.DiagStorage; 237f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot } else { 238f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot freeStorage(); 239f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot } 240f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 241f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot return *this; 242f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot } 243f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 244f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot PartialDiagnostic &operator=(PartialDiagnostic &&Other) { 245f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot freeStorage(); 246f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 247f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot DiagID = Other.DiagID; 248f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot DiagStorage = Other.DiagStorage; 249f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot Allocator = Other.Allocator; 250f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 251f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot Other.DiagStorage = nullptr; 252f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot return *this; 253f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot } 254f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 255f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot ~PartialDiagnostic() { 256f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot freeStorage(); 257f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot } 258f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 259f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot void swap(PartialDiagnostic &PD) { 260f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot std::swap(DiagID, PD.DiagID); 261f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot std::swap(DiagStorage, PD.DiagStorage); 262f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot std::swap(Allocator, PD.Allocator); 263f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot } 264f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 265f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot unsigned getDiagID() const { return DiagID; } 266f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 267f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot void AddTaggedVal(intptr_t V, DiagnosticsEngine::ArgumentKind Kind) const { 268f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot if (!DiagStorage) 269f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot DiagStorage = getStorage(); 270f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 271f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot assert(DiagStorage->NumDiagArgs < Storage::MaxArguments && 272f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot "Too many arguments to diagnostic!"); 273f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot DiagStorage->DiagArgumentsKind[DiagStorage->NumDiagArgs] = Kind; 274f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot DiagStorage->DiagArgumentsVal[DiagStorage->NumDiagArgs++] = V; 275f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot } 276f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 277f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot void AddString(StringRef V) const { 278f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot if (!DiagStorage) 279f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot DiagStorage = getStorage(); 280f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 281f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot assert(DiagStorage->NumDiagArgs < Storage::MaxArguments && 282f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot "Too many arguments to diagnostic!"); 283f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot DiagStorage->DiagArgumentsKind[DiagStorage->NumDiagArgs] 284f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot = DiagnosticsEngine::ak_std_string; 285f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot DiagStorage->DiagArgumentsStr[DiagStorage->NumDiagArgs++] = V; 286f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot } 287f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 288f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot void Emit(const DiagnosticBuilder &DB) const { 289f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot if (!DiagStorage) 290f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot return; 291f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 292f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot // Add all arguments. 293f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot for (unsigned i = 0, e = DiagStorage->NumDiagArgs; i != e; ++i) { 294f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot if ((DiagnosticsEngine::ArgumentKind)DiagStorage->DiagArgumentsKind[i] 295f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot == DiagnosticsEngine::ak_std_string) 296f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot DB.AddString(DiagStorage->DiagArgumentsStr[i]); 297f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot else 298f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot DB.AddTaggedVal(DiagStorage->DiagArgumentsVal[i], 299f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot (DiagnosticsEngine::ArgumentKind)DiagStorage->DiagArgumentsKind[i]); 300f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot } 301f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 302f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot // Add all ranges. 303f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot for (const CharSourceRange &Range : DiagStorage->DiagRanges) 304f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot DB.AddSourceRange(Range); 305f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 306f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot // Add all fix-its. 307f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot for (const FixItHint &Fix : DiagStorage->FixItHints) 308f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot DB.AddFixItHint(Fix); 309f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot } 310f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 311f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot void EmitToString(DiagnosticsEngine &Diags, 312f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot SmallVectorImpl<char> &Buf) const { 313f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot // FIXME: It should be possible to render a diagnostic to a string without 314f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot // messing with the state of the diagnostics engine. 315f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot DiagnosticBuilder DB(Diags.Report(getDiagID())); 316f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot Emit(DB); 317f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot DB.FlushCounts(); 318f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot Diagnostic(&Diags).FormatDiagnostic(Buf); 319f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot DB.Clear(); 320f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot Diags.Clear(); 321f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot } 322f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 323f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// \brief Clear out this partial diagnostic, giving it a new diagnostic ID 324f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// and removing all of its arguments, ranges, and fix-it hints. 325f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot void Reset(unsigned DiagID = 0) { 326f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot this->DiagID = DiagID; 327f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot freeStorage(); 328f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot } 329f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 330f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot bool hasStorage() const { return DiagStorage != nullptr; } 331f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 332f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot friend const PartialDiagnostic &operator<<(const PartialDiagnostic &PD, 333f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot unsigned I) { 334f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot PD.AddTaggedVal(I, DiagnosticsEngine::ak_uint); 335f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot return PD; 336f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot } 337f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 338f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot friend const PartialDiagnostic &operator<<(const PartialDiagnostic &PD, 339f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot int I) { 340f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot PD.AddTaggedVal(I, DiagnosticsEngine::ak_sint); 341f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot return PD; 342f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot } 343f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 344f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot friend inline const PartialDiagnostic &operator<<(const PartialDiagnostic &PD, 345f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot const char *S) { 346f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot PD.AddTaggedVal(reinterpret_cast<intptr_t>(S), 347f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot DiagnosticsEngine::ak_c_string); 348f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot return PD; 349f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot } 350f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 351f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot friend inline const PartialDiagnostic &operator<<(const PartialDiagnostic &PD, 352f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot StringRef S) { 353f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 354f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot PD.AddString(S); 355f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot return PD; 356f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot } 357f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 358f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot friend inline const PartialDiagnostic &operator<<(const PartialDiagnostic &PD, 359f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot const IdentifierInfo *II) { 360f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot PD.AddTaggedVal(reinterpret_cast<intptr_t>(II), 361f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot DiagnosticsEngine::ak_identifierinfo); 362f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot return PD; 363f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot } 364f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 365f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot // Adds a DeclContext to the diagnostic. The enable_if template magic is here 366f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot // so that we only match those arguments that are (statically) DeclContexts; 367f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot // other arguments that derive from DeclContext (e.g., RecordDecls) will not 368f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot // match. 369f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot template<typename T> 370f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot friend inline 371f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot typename std::enable_if<std::is_same<T, DeclContext>::value, 372f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot const PartialDiagnostic &>::type 373f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot operator<<(const PartialDiagnostic &PD, T *DC) { 374f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot PD.AddTaggedVal(reinterpret_cast<intptr_t>(DC), 375f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot DiagnosticsEngine::ak_declcontext); 376f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot return PD; 377f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot } 378f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 379f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot friend inline const PartialDiagnostic &operator<<(const PartialDiagnostic &PD, 380f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot SourceRange R) { 381f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot PD.AddSourceRange(CharSourceRange::getTokenRange(R)); 382f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot return PD; 383f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot } 384f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 385f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot friend inline const PartialDiagnostic &operator<<(const PartialDiagnostic &PD, 386f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot const CharSourceRange &R) { 387f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot PD.AddSourceRange(R); 388f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot return PD; 389f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot } 390f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 391f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot friend const PartialDiagnostic &operator<<(const PartialDiagnostic &PD, 392f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot const FixItHint &Hint) { 393f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot PD.AddFixItHint(Hint); 394f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot return PD; 395f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot } 396f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 397f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot}; 398f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 399f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotinline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB, 400f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot const PartialDiagnostic &PD) { 401f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot PD.Emit(DB); 402f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot return DB; 403f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot} 404f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 405f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// \brief A partial diagnostic along with the source location where this 406f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// diagnostic occurs. 407f3014761c955345d6e05491608e73228d014afbandroid-build-team Robottypedef std::pair<SourceLocation, PartialDiagnostic> PartialDiagnosticAt; 408f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 409f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot} // end namespace clang 410f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot#endif 411