[cfe-commits] r119730 - in /cfe/trunk: include/clang/AST/ include/clang/Basic/ include/clang/Lex/ include/clang/Rewrite/ lib/AST/ lib/Basic/ lib/Checker/ lib/CodeGen/ lib/Driver/ lib/Frontend/ lib/Parse/ lib/Rewrite/ lib/Sema/ lib/Serialization/ tools/driver/ tools/libclang/

Argyrios Kyrtzidis akyrtzi at gmail.com
Thu Nov 18 12:06:41 PST 2010


Author: akirtzidis
Date: Thu Nov 18 14:06:41 2010
New Revision: 119730

URL: http://llvm.org/viewvc/llvm-project?rev=119730&view=rev
Log:
Refactoring of Diagnostic class.

-Move the stuff of Diagnostic related to creating/querying diagnostic IDs into a new DiagnosticIDs class.
-DiagnosticIDs can be shared among multiple Diagnostics for multiple translation units.
-The rest of the state in Diagnostic object is considered related and tied to one translation unit.
-Have Diagnostic point to the SourceManager that is related with. Diagnostic can now accept just a
   SourceLocation instead of a FullSourceLoc.
-Reflect the changes to various interfaces.

Added:
    cfe/trunk/include/clang/Basic/DiagnosticIDs.h
    cfe/trunk/lib/Basic/DiagnosticIDs.cpp
Modified:
    cfe/trunk/include/clang/AST/ASTImporter.h
    cfe/trunk/include/clang/Basic/Diagnostic.h
    cfe/trunk/include/clang/Basic/SourceManager.h
    cfe/trunk/include/clang/Lex/Preprocessor.h
    cfe/trunk/include/clang/Rewrite/FixItRewriter.h
    cfe/trunk/lib/AST/ASTImporter.cpp
    cfe/trunk/lib/AST/RecordLayoutBuilder.cpp
    cfe/trunk/lib/Basic/Diagnostic.cpp
    cfe/trunk/lib/Basic/SourceManager.cpp
    cfe/trunk/lib/Checker/PathDiagnostic.cpp
    cfe/trunk/lib/CodeGen/CGDebugInfo.cpp
    cfe/trunk/lib/CodeGen/CodeGenAction.cpp
    cfe/trunk/lib/CodeGen/Mangle.cpp
    cfe/trunk/lib/Driver/Driver.cpp
    cfe/trunk/lib/Frontend/ASTMerge.cpp
    cfe/trunk/lib/Frontend/CompilerInstance.cpp
    cfe/trunk/lib/Frontend/TextDiagnosticPrinter.cpp
    cfe/trunk/lib/Parse/Parser.cpp
    cfe/trunk/lib/Rewrite/FixItRewriter.cpp
    cfe/trunk/lib/Rewrite/HTMLRewrite.cpp
    cfe/trunk/lib/Sema/DeclSpec.cpp
    cfe/trunk/lib/Sema/Sema.cpp
    cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp
    cfe/trunk/lib/Serialization/ASTReader.cpp
    cfe/trunk/tools/driver/cc1_main.cpp
    cfe/trunk/tools/driver/cc1as_main.cpp
    cfe/trunk/tools/driver/driver.cpp
    cfe/trunk/tools/libclang/CIndexCodeCompletion.cpp

Modified: cfe/trunk/include/clang/AST/ASTImporter.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ASTImporter.h?rev=119730&r1=119729&r2=119730&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/ASTImporter.h (original)
+++ cfe/trunk/include/clang/AST/ASTImporter.h Thu Nov 18 14:06:41 2010
@@ -49,9 +49,6 @@
 
     const FileSystemOptions &ToFileSystemOpts, &FromFileSystemOpts;
     
-    /// \brief The diagnostics object that we should use to emit diagnostics.
-    Diagnostic &Diags;
-    
     /// \brief Mapping from the already-imported types in the "from" context
     /// to the corresponding types in the "to" context.
     llvm::DenseMap<Type *, Type *> ImportedTypes;
@@ -77,8 +74,7 @@
     NonEquivalentDeclSet NonEquivalentDecls;
     
   public:
-    ASTImporter(Diagnostic &Diags,
-                ASTContext &ToContext, FileManager &ToFileManager,
+    ASTImporter(ASTContext &ToContext, FileManager &ToFileManager,
                 const FileSystemOptions &ToFileSystemOpts,
                 ASTContext &FromContext, FileManager &FromFileManager,
                 const FileSystemOptions &FromFileSystemOpts);
@@ -217,9 +213,6 @@
 
     /// \brief Retrieve the file manager that AST nodes are being imported from.
     FileManager &getFromFileManager() const { return FromFileManager; }
-
-    /// \brief Retrieve the diagnostic formatter.
-    Diagnostic &getDiags() const { return Diags; }
     
     /// \brief Report a diagnostic in the "to" context.
     DiagnosticBuilder ToDiag(SourceLocation Loc, unsigned DiagID);

Modified: cfe/trunk/include/clang/Basic/Diagnostic.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/Diagnostic.h?rev=119730&r1=119729&r2=119730&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/Diagnostic.h (original)
+++ cfe/trunk/include/clang/Basic/Diagnostic.h Thu Nov 18 14:06:41 2010
@@ -14,78 +14,22 @@
 #ifndef LLVM_CLANG_DIAGNOSTIC_H
 #define LLVM_CLANG_DIAGNOSTIC_H
 
+#include "clang/Basic/DiagnosticIDs.h"
 #include "clang/Basic/SourceLocation.h"
 #include "llvm/ADT/IntrusiveRefCntPtr.h"
 #include "llvm/ADT/OwningPtr.h"
-#include "llvm/ADT/StringRef.h"
 #include "llvm/Support/type_traits.h"
-#include "llvm/System/DataTypes.h"
-#include <string>
-#include <vector>
-#include <cassert>
 
-namespace llvm {
-  template <typename T> class SmallVectorImpl;
-}
+#include <vector>
 
 namespace clang {
-  class DeclContext;
-  class DiagnosticBuilder;
   class DiagnosticClient;
-  class FileManager;
+  class DiagnosticBuilder;
   class IdentifierInfo;
+  class DeclContext;
   class LangOptions;
-  class PartialDiagnostic;
   class Preprocessor;
 
-  // Import the diagnostic enums themselves.
-  namespace diag {
-    // Start position for diagnostics.
-    enum {
-      DIAG_START_DRIVER   =                        300,
-      DIAG_START_FRONTEND = DIAG_START_DRIVER   +  100,
-      DIAG_START_LEX      = DIAG_START_FRONTEND +  100,
-      DIAG_START_PARSE    = DIAG_START_LEX      +  300,
-      DIAG_START_AST      = DIAG_START_PARSE    +  300,
-      DIAG_START_SEMA     = DIAG_START_AST      +  100,
-      DIAG_START_ANALYSIS = DIAG_START_SEMA     + 1500,
-      DIAG_UPPER_LIMIT    = DIAG_START_ANALYSIS +  100
-    };
-
-    class CustomDiagInfo;
-
-    /// diag::kind - All of the diagnostics that can be emitted by the frontend.
-    typedef unsigned kind;
-
-    // Get typedefs for common diagnostics.
-    enum {
-#define DIAG(ENUM,FLAGS,DEFAULT_MAPPING,DESC,GROUP,SFINAE,CATEGORY) ENUM,
-#include "clang/Basic/DiagnosticCommonKinds.inc"
-      NUM_BUILTIN_COMMON_DIAGNOSTICS
-#undef DIAG
-    };
-
-    /// Enum values that allow the client to map NOTEs, WARNINGs, and EXTENSIONs
-    /// to either MAP_IGNORE (nothing), MAP_WARNING (emit a warning), MAP_ERROR
-    /// (emit as an error).  It allows clients to map errors to
-    /// MAP_ERROR/MAP_DEFAULT or MAP_FATAL (stop emitting diagnostics after this
-    /// one).
-    enum Mapping {
-      // NOTE: 0 means "uncomputed".
-      MAP_IGNORE  = 1,     //< Map this diagnostic to nothing, ignore it.
-      MAP_WARNING = 2,     //< Map this diagnostic to a warning.
-      MAP_ERROR   = 3,     //< Map this diagnostic to an error.
-      MAP_FATAL   = 4,     //< Map this diagnostic to a fatal error.
-
-      /// Map this diagnostic to "warning", but make it immune to -Werror.  This
-      /// happens when you specify -Wno-error=foo.
-      MAP_WARNING_NO_WERROR = 5,
-      /// Map this diagnostic to "error", but make it immune to -Wfatal-errors.
-      /// This happens for -Wno-fatal-errors=foo.
-      MAP_ERROR_NO_WFATAL = 6
-    };
-  }
-
 /// \brief Annotates a diagnostic with some code that should be
 /// inserted, removed, or replaced to fix the problem.
 ///
@@ -154,12 +98,17 @@
 /// Diagnostic - This concrete class is used by the front-end to report
 /// problems and issues.  It massages the diagnostics (e.g. handling things like
 /// "report warnings as errors" and passes them off to the DiagnosticClient for
-/// reporting to the user.
+/// reporting to the user. Diagnostic is tied to one translation unit and
+/// one SourceManager.
 class Diagnostic : public llvm::RefCountedBase<Diagnostic> {
 public:
   /// Level - The level of the diagnostic, after it has been through mapping.
   enum Level {
-    Ignored, Note, Warning, Error, Fatal
+    Ignored = DiagnosticIDs::Ignored,
+    Note = DiagnosticIDs::Note,
+    Warning = DiagnosticIDs::Warning,
+    Error = DiagnosticIDs::Error,
+    Fatal = DiagnosticIDs::Fatal
   };
 
   /// ExtensionHandling - How do we handle otherwise-unmapped extension?  This
@@ -204,7 +153,10 @@
   unsigned TemplateBacktraceLimit; // Cap on depth of template backtrace stack,
                                    // 0 -> no limit.
   ExtensionHandling ExtBehavior; // Map extensions onto warnings or errors?
-  llvm::OwningPtr<DiagnosticClient> Client;
+  llvm::IntrusiveRefCntPtr<DiagnosticIDs> Diags;
+  DiagnosticClient *Client;
+  bool OwnsDiagClient;
+  SourceManager *SourceMgr;
   
   /// DiagMappings - Mapping information for diagnostics.  Mapping info is
   /// packed into four bits per diagnostic.  The low three bits are the mapping
@@ -238,14 +190,11 @@
   /// LastDiagLevel - This is the level of the last diagnostic emitted.  This is
   /// used to emit continuation diagnostics with the same level as the
   /// diagnostic that they follow.
-  Diagnostic::Level LastDiagLevel;
+  DiagnosticIDs::Level LastDiagLevel;
 
   unsigned NumWarnings;       // Number of warnings reported
   unsigned NumErrors;         // Number of errors reported
   unsigned NumErrorsSuppressed; // Number of errors suppressed
-  
-  /// CustomDiagInfo - Information for uniquing and looking up custom diags.
-  diag::CustomDiagInfo *CustomDiagInfo;
 
   /// ArgToStringFn - A function pointer that converts an opaque diagnostic
   /// argument to a strings.  This takes the modifiers and argument that was
@@ -278,19 +227,36 @@
   std::string DelayedDiagArg2;
 
 public:
-  explicit Diagnostic(DiagnosticClient *client = 0);
+  explicit Diagnostic(const llvm::IntrusiveRefCntPtr<DiagnosticIDs> &Diags,
+                      DiagnosticClient *client = 0,
+                      bool ShouldOwnClient = true);
   ~Diagnostic();
 
-  //===--------------------------------------------------------------------===//
-  //  Diagnostic characterization methods, used by a client to customize how
-  //
+  const llvm::IntrusiveRefCntPtr<DiagnosticIDs> &getDiagnosticIDs() const {
+    return Diags;
+  }
+
+  DiagnosticClient *getClient() { return Client; }
+  const DiagnosticClient *getClient() const { return Client; }
 
-  DiagnosticClient *getClient() { return Client.get(); }
-  const DiagnosticClient *getClient() const { return Client.get(); }
-  
   /// \brief Return the current diagnostic client along with ownership of that
   /// client.
-  DiagnosticClient *takeClient() { return Client.take(); }
+  DiagnosticClient *takeClient() {
+    OwnsDiagClient = false;
+    return Client;
+  }
+
+  bool hasSourceManager() const { return SourceMgr != 0; }
+  SourceManager &getSourceManager() const {
+    assert(SourceMgr && "SourceManager not set!");
+    return *SourceMgr;
+  }
+  void setSourceManager(SourceManager *SrcMgr) { SourceMgr = SrcMgr; }
+
+  //===--------------------------------------------------------------------===//
+  //  Diagnostic characterization methods, used by a client to customize how
+  //  diagnostics are emitted.
+  //
 
   /// pushMappings - Copies the current DiagMappings and pushes the new copy
   /// onto the top of the stack.
@@ -304,8 +270,12 @@
 
   /// \brief Set the diagnostic client associated with this diagnostic object.
   ///
-  /// The diagnostic object takes ownership of \c client.
-  void setClient(DiagnosticClient* client) { Client.reset(client); }
+  /// \param ShouldOwnClient true if the diagnostic object should take
+  /// ownership of \c client.
+  void setClient(DiagnosticClient *client, bool ShouldOwnClient = true) {
+    Client = client;
+    OwnsDiagClient = ShouldOwnClient;
+  }
 
   /// setErrorLimit - Specify a limit for the number of errors we should
   /// emit before giving up.  Zero disables the limit.
@@ -361,7 +331,7 @@
   /// \brief Pretend that the last diagnostic issued was ignored. This can
   /// be used by clients who suppress diagnostics themselves.
   void setLastDiagnosticIgnored() {
-    LastDiagLevel = Ignored;
+    LastDiagLevel = DiagnosticIDs::Ignored;
   }
   
   /// setExtensionHandlingBehavior - This controls whether otherwise-unmapped
@@ -384,7 +354,7 @@
   void setDiagnosticMapping(diag::kind Diag, diag::Mapping Map) {
     assert(Diag < diag::DIAG_UPPER_LIMIT &&
            "Can only map builtin diagnostics");
-    assert((isBuiltinWarningOrExtension(Diag) ||
+    assert((Diags->isBuiltinWarningOrExtension(Diag) ||
             (Map == diag::MAP_FATAL || Map == diag::MAP_ERROR)) &&
            "Cannot map errors into warnings!");
     setDiagnosticMappingInternal(Diag, Map, true);
@@ -393,7 +363,9 @@
   /// setDiagnosticGroupMapping - Change an entire diagnostic group (e.g.
   /// "unknown-pragmas" to have the specified mapping.  This returns true and
   /// ignores the request if "Group" was unknown, false otherwise.
-  bool setDiagnosticGroupMapping(const char *Group, diag::Mapping Map);
+  bool setDiagnosticGroupMapping(const char *Group, diag::Mapping Map) {
+    return Diags->setDiagnosticGroupMapping(Group, Map, *this);
+  }
 
   bool hasErrorOccurred() const { return ErrorOccurred; }
   bool hasFatalErrorOccurred() const { return FatalErrorOccurred; }
@@ -406,11 +378,16 @@
     this->NumWarnings = NumWarnings;
   }
 
+  void setNumErrors(unsigned NumErrors) {
+    this->NumErrors = NumErrors;
+  }
+
   /// getCustomDiagID - Return an ID for a diagnostic with the specified message
   /// and level.  If this is the first request for this diagnosic, it is
   /// registered and created, otherwise the existing ID is returned.
-  unsigned getCustomDiagID(Level L, llvm::StringRef Message);
-
+  unsigned getCustomDiagID(Level L, llvm::StringRef Message) {
+    return Diags->getCustomDiagID((DiagnosticIDs::Level)L, Message);
+  }
 
   /// ConvertArgToString - This method converts a diagnostic argument (as an
   /// intptr_t) into the string that represents it.
@@ -436,92 +413,19 @@
   // Diagnostic classification and reporting interfaces.
   //
 
-  /// getDescription - Given a diagnostic ID, return a description of the
-  /// issue.
-  const char *getDescription(unsigned DiagID) const;
-
-  /// isNoteWarningOrExtension - Return true if the unmapped diagnostic
-  /// level of the specified diagnostic ID is a Warning or Extension.
-  /// This only works on builtin diagnostics, not custom ones, and is not legal to
-  /// call on NOTEs.
-  static bool isBuiltinWarningOrExtension(unsigned DiagID);
-
-  /// \brief Determine whether the given built-in diagnostic ID is a
-  /// Note.
-  static bool isBuiltinNote(unsigned DiagID);
-
-  /// isBuiltinExtensionDiag - Determine whether the given built-in diagnostic
-  /// ID is for an extension of some sort.
-  ///
-  static bool isBuiltinExtensionDiag(unsigned DiagID) {
-    bool ignored;
-    return isBuiltinExtensionDiag(DiagID, ignored);
-  }
-  
-  /// isBuiltinExtensionDiag - Determine whether the given built-in diagnostic
-  /// ID is for an extension of some sort.  This also returns EnabledByDefault,
-  /// which is set to indicate whether the diagnostic is ignored by default (in
-  /// which case -pedantic enables it) or treated as a warning/error by default.
-  ///
-  static bool isBuiltinExtensionDiag(unsigned DiagID, bool &EnabledByDefault);
-  
-
-  /// getWarningOptionForDiag - Return the lowest-level warning option that
-  /// enables the specified diagnostic.  If there is no -Wfoo flag that controls
-  /// the diagnostic, this returns null.
-  static const char *getWarningOptionForDiag(unsigned DiagID);
-
-  /// getWarningOptionForDiag - Return the category number that a specified
-  /// DiagID belongs to, or 0 if no category.
-  static unsigned getCategoryNumberForDiag(unsigned DiagID);
-
-  /// getCategoryNameFromID - Given a category ID, return the name of the
-  /// category.
-  static const char *getCategoryNameFromID(unsigned CategoryID);
-  
-  /// \brief Enumeration describing how the the emission of a diagnostic should
-  /// be treated when it occurs during C++ template argument deduction.
-  enum SFINAEResponse {
-    /// \brief The diagnostic should not be reported, but it should cause
-    /// template argument deduction to fail.
-    ///
-    /// The vast majority of errors that occur during template argument 
-    /// deduction fall into this category.
-    SFINAE_SubstitutionFailure,
-    
-    /// \brief The diagnostic should be suppressed entirely.
-    ///
-    /// Warnings generally fall into this category.
-    SFINAE_Suppress,
-    
-    /// \brief The diagnostic should be reported.
-    ///
-    /// The diagnostic should be reported. Various fatal errors (e.g., 
-    /// template instantiation depth exceeded) fall into this category.
-    SFINAE_Report
-  };
-  
-  /// \brief Determines whether the given built-in diagnostic ID is
-  /// for an error that is suppressed if it occurs during C++ template
-  /// argument deduction.
-  ///
-  /// When an error is suppressed due to SFINAE, the template argument
-  /// deduction fails but no diagnostic is emitted. Certain classes of
-  /// errors, such as those errors that involve C++ access control,
-  /// are not SFINAE errors.
-  static SFINAEResponse getDiagnosticSFINAEResponse(unsigned DiagID);
-
   /// getDiagnosticLevel - Based on the way the client configured the Diagnostic
   /// object, classify the specified diagnostic ID into a Level, consumable by
   /// the DiagnosticClient.
-  Level getDiagnosticLevel(unsigned DiagID) const;
+  Level getDiagnosticLevel(unsigned DiagID) const {
+    return (Level)Diags->getDiagnosticLevel(DiagID, *this);
+  }
 
   /// Report - Issue the message to the client.  @c DiagID is a member of the
   /// @c diag::kind enum.  This actually returns aninstance of DiagnosticBuilder
   /// which emits the diagnostics (through @c ProcessDiag) when it is destroyed.
   /// @c Pos represents the source location associated with the diagnostic,
   /// which can be an invalid location if no position information is available.
-  inline DiagnosticBuilder Report(FullSourceLoc Pos, unsigned DiagID);
+  inline DiagnosticBuilder Report(SourceLocation Pos, unsigned DiagID);
   inline DiagnosticBuilder Report(unsigned DiagID);
 
   /// \brief Determine whethere there is already a diagnostic in flight.
@@ -572,23 +476,20 @@
     DiagMappingsStack.back().setMapping((diag::kind)DiagId, Map);
   }
 
-  /// getDiagnosticLevel - This is an internal implementation helper used when
-  /// DiagClass is already known.
-  Level getDiagnosticLevel(unsigned DiagID, unsigned DiagClass) const;
-
   // This is private state used by DiagnosticBuilder.  We put it here instead of
   // in DiagnosticBuilder in order to keep DiagnosticBuilder a small lightweight
   // object.  This implementation choice means that we can only have one
   // diagnostic "in flight" at a time, but this seems to be a reasonable
   // tradeoff to keep these objects small.  Assertions verify that only one
   // diagnostic is in flight at a time.
+  friend class DiagnosticIDs;
   friend class DiagnosticBuilder;
   friend class DiagnosticInfo;
   friend class PartialDiagnostic;
   
   /// CurDiagLoc - This is the location of the current diagnostic that is in
   /// flight.
-  FullSourceLoc CurDiagLoc;
+  SourceLocation CurDiagLoc;
 
   /// CurDiagID - This is the ID of the current diagnostic that is in flight.
   /// This is set to ~0U when there is no diagnostic in flight.
@@ -640,7 +541,9 @@
   ///
   /// \returns true if the diagnostic was emitted, false if it was
   /// suppressed.
-  bool ProcessDiag();
+  bool ProcessDiag() {
+    return Diags->ProcessDiag(*this);
+  }
 
   friend class ASTReader;
   friend class ASTWriter;
@@ -835,14 +738,15 @@
 /// Report - Issue the message to the client.  DiagID is a member of the
 /// diag::kind enum.  This actually returns a new instance of DiagnosticBuilder
 /// which emits the diagnostics (through ProcessDiag) when it is destroyed.
-inline DiagnosticBuilder Diagnostic::Report(FullSourceLoc Loc, unsigned DiagID){
+inline DiagnosticBuilder Diagnostic::Report(SourceLocation Loc,
+                                            unsigned DiagID){
   assert(CurDiagID == ~0U && "Multiple diagnostics in flight at once!");
   CurDiagLoc = Loc;
   CurDiagID = DiagID;
   return DiagnosticBuilder(this);
 }
 inline DiagnosticBuilder Diagnostic::Report(unsigned DiagID) {
-  return Report(FullSourceLoc(), DiagID);
+  return Report(SourceLocation(), DiagID);
 }
 
 //===----------------------------------------------------------------------===//
@@ -859,7 +763,9 @@
 
   const Diagnostic *getDiags() const { return DiagObj; }
   unsigned getID() const { return DiagObj->CurDiagID; }
-  const FullSourceLoc &getLocation() const { return DiagObj->CurDiagLoc; }
+  const SourceLocation &getLocation() const { return DiagObj->CurDiagLoc; }
+  bool hasSourceManager() const { return DiagObj->hasSourceManager(); }
+  SourceManager &getSourceManager() const { return DiagObj->getSourceManager();}
 
   unsigned getNumArgs() const { return DiagObj->NumDiagArgs; }
 

Added: cfe/trunk/include/clang/Basic/DiagnosticIDs.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticIDs.h?rev=119730&view=auto
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticIDs.h (added)
+++ cfe/trunk/include/clang/Basic/DiagnosticIDs.h Thu Nov 18 14:06:41 2010
@@ -0,0 +1,203 @@
+//===--- DiagnosticIDs.h - Diagnostic IDs Handling --------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines the Diagnostic IDs-related interfaces.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_DIAGNOSTICIDS_H
+#define LLVM_CLANG_DIAGNOSTICIDS_H
+
+#include "llvm/ADT/IntrusiveRefCntPtr.h"
+#include "llvm/ADT/StringRef.h"
+
+namespace clang {
+  class Diagnostic;
+
+  // Import the diagnostic enums themselves.
+  namespace diag {
+    // Start position for diagnostics.
+    enum {
+      DIAG_START_DRIVER   =                        300,
+      DIAG_START_FRONTEND = DIAG_START_DRIVER   +  100,
+      DIAG_START_LEX      = DIAG_START_FRONTEND +  100,
+      DIAG_START_PARSE    = DIAG_START_LEX      +  300,
+      DIAG_START_AST      = DIAG_START_PARSE    +  300,
+      DIAG_START_SEMA     = DIAG_START_AST      +  100,
+      DIAG_START_ANALYSIS = DIAG_START_SEMA     + 1500,
+      DIAG_UPPER_LIMIT    = DIAG_START_ANALYSIS +  100
+    };
+
+    class CustomDiagInfo;
+
+    /// diag::kind - All of the diagnostics that can be emitted by the frontend.
+    typedef unsigned kind;
+
+    // Get typedefs for common diagnostics.
+    enum {
+#define DIAG(ENUM,FLAGS,DEFAULT_MAPPING,DESC,GROUP,SFINAE,CATEGORY) ENUM,
+#include "clang/Basic/DiagnosticCommonKinds.inc"
+      NUM_BUILTIN_COMMON_DIAGNOSTICS
+#undef DIAG
+    };
+
+    /// Enum values that allow the client to map NOTEs, WARNINGs, and EXTENSIONs
+    /// to either MAP_IGNORE (nothing), MAP_WARNING (emit a warning), MAP_ERROR
+    /// (emit as an error).  It allows clients to map errors to
+    /// MAP_ERROR/MAP_DEFAULT or MAP_FATAL (stop emitting diagnostics after this
+    /// one).
+    enum Mapping {
+      // NOTE: 0 means "uncomputed".
+      MAP_IGNORE  = 1,     //< Map this diagnostic to nothing, ignore it.
+      MAP_WARNING = 2,     //< Map this diagnostic to a warning.
+      MAP_ERROR   = 3,     //< Map this diagnostic to an error.
+      MAP_FATAL   = 4,     //< Map this diagnostic to a fatal error.
+
+      /// Map this diagnostic to "warning", but make it immune to -Werror.  This
+      /// happens when you specify -Wno-error=foo.
+      MAP_WARNING_NO_WERROR = 5,
+      /// Map this diagnostic to "error", but make it immune to -Wfatal-errors.
+      /// This happens for -Wno-fatal-errors=foo.
+      MAP_ERROR_NO_WFATAL = 6
+    };
+  }
+
+/// \brief Used for handling and querying diagnostic IDs. Can be used and shared
+/// by multiple Diagnostics for multiple translation units.
+class DiagnosticIDs : public llvm::RefCountedBase<DiagnosticIDs> {
+public:
+  /// Level - The level of the diagnostic, after it has been through mapping.
+  enum Level {
+    Ignored, Note, Warning, Error, Fatal
+  };
+
+private:
+  /// CustomDiagInfo - Information for uniquing and looking up custom diags.
+  diag::CustomDiagInfo *CustomDiagInfo;
+
+public:
+  DiagnosticIDs();
+  ~DiagnosticIDs();
+
+  /// getCustomDiagID - Return an ID for a diagnostic with the specified message
+  /// and level.  If this is the first request for this diagnosic, it is
+  /// registered and created, otherwise the existing ID is returned.
+  unsigned getCustomDiagID(Level L, llvm::StringRef Message);
+
+  //===--------------------------------------------------------------------===//
+  // Diagnostic classification and reporting interfaces.
+  //
+
+  /// getDescription - Given a diagnostic ID, return a description of the
+  /// issue.
+  const char *getDescription(unsigned DiagID) const;
+
+  /// isNoteWarningOrExtension - Return true if the unmapped diagnostic
+  /// level of the specified diagnostic ID is a Warning or Extension.
+  /// This only works on builtin diagnostics, not custom ones, and is not legal to
+  /// call on NOTEs.
+  static bool isBuiltinWarningOrExtension(unsigned DiagID);
+
+  /// \brief Determine whether the given built-in diagnostic ID is a
+  /// Note.
+  static bool isBuiltinNote(unsigned DiagID);
+
+  /// isBuiltinExtensionDiag - Determine whether the given built-in diagnostic
+  /// ID is for an extension of some sort.
+  ///
+  static bool isBuiltinExtensionDiag(unsigned DiagID) {
+    bool ignored;
+    return isBuiltinExtensionDiag(DiagID, ignored);
+  }
+  
+  /// isBuiltinExtensionDiag - Determine whether the given built-in diagnostic
+  /// ID is for an extension of some sort.  This also returns EnabledByDefault,
+  /// which is set to indicate whether the diagnostic is ignored by default (in
+  /// which case -pedantic enables it) or treated as a warning/error by default.
+  ///
+  static bool isBuiltinExtensionDiag(unsigned DiagID, bool &EnabledByDefault);
+  
+
+  /// getWarningOptionForDiag - Return the lowest-level warning option that
+  /// enables the specified diagnostic.  If there is no -Wfoo flag that controls
+  /// the diagnostic, this returns null.
+  static const char *getWarningOptionForDiag(unsigned DiagID);
+
+  /// getWarningOptionForDiag - Return the category number that a specified
+  /// DiagID belongs to, or 0 if no category.
+  static unsigned getCategoryNumberForDiag(unsigned DiagID);
+
+  /// getCategoryNameFromID - Given a category ID, return the name of the
+  /// category.
+  static const char *getCategoryNameFromID(unsigned CategoryID);
+  
+  /// \brief Enumeration describing how the the emission of a diagnostic should
+  /// be treated when it occurs during C++ template argument deduction.
+  enum SFINAEResponse {
+    /// \brief The diagnostic should not be reported, but it should cause
+    /// template argument deduction to fail.
+    ///
+    /// The vast majority of errors that occur during template argument 
+    /// deduction fall into this category.
+    SFINAE_SubstitutionFailure,
+    
+    /// \brief The diagnostic should be suppressed entirely.
+    ///
+    /// Warnings generally fall into this category.
+    SFINAE_Suppress,
+    
+    /// \brief The diagnostic should be reported.
+    ///
+    /// The diagnostic should be reported. Various fatal errors (e.g., 
+    /// template instantiation depth exceeded) fall into this category.
+    SFINAE_Report
+  };
+  
+  /// \brief Determines whether the given built-in diagnostic ID is
+  /// for an error that is suppressed if it occurs during C++ template
+  /// argument deduction.
+  ///
+  /// When an error is suppressed due to SFINAE, the template argument
+  /// deduction fails but no diagnostic is emitted. Certain classes of
+  /// errors, such as those errors that involve C++ access control,
+  /// are not SFINAE errors.
+  static SFINAEResponse getDiagnosticSFINAEResponse(unsigned DiagID);
+
+private:
+  /// setDiagnosticGroupMapping - Change an entire diagnostic group (e.g.
+  /// "unknown-pragmas" to have the specified mapping.  This returns true and
+  /// ignores the request if "Group" was unknown, false otherwise.
+  bool setDiagnosticGroupMapping(const char *Group, diag::Mapping Map,
+                                 Diagnostic &Diag) const;
+
+  /// getDiagnosticLevel - Based on the way the client configured the Diagnostic
+  /// object, classify the specified diagnostic ID into a Level, consumable by
+  /// the DiagnosticClient.
+  DiagnosticIDs::Level getDiagnosticLevel(unsigned DiagID,
+                                          const Diagnostic &Diag) const;
+
+  /// getDiagnosticLevel - This is an internal implementation helper used when
+  /// DiagClass is already known.
+  DiagnosticIDs::Level getDiagnosticLevel(unsigned DiagID,
+                                          unsigned DiagClass,
+                                          const Diagnostic &Diag) const;
+
+  /// ProcessDiag - This is the method used to report a diagnostic that is
+  /// finally fully formed.
+  ///
+  /// \returns true if the diagnostic was emitted, false if it was
+  /// suppressed.
+  bool ProcessDiag(Diagnostic &Diag) const;
+
+  friend class Diagnostic;
+};
+
+}  // end namespace clang
+
+#endif

Modified: cfe/trunk/include/clang/Basic/SourceManager.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/SourceManager.h?rev=119730&r1=119729&r2=119730&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/SourceManager.h (original)
+++ cfe/trunk/include/clang/Basic/SourceManager.h Thu Nov 18 14:06:41 2010
@@ -432,12 +432,7 @@
   void operator=(const SourceManager&);
 public:
   SourceManager(Diagnostic &Diag, FileManager &FileMgr,
-                const FileSystemOptions &FSOpts)
-    : Diag(Diag), FileMgr(FileMgr), FileSystemOpts(FSOpts),
-      ExternalSLocEntries(0), LineTable(0), NumLinearScans(0),
-      NumBinaryProbes(0) {
-    clearIDTables();
-  }
+                const FileSystemOptions &FSOpts);
   ~SourceManager();
 
   void clearIDTables();

Modified: cfe/trunk/include/clang/Lex/Preprocessor.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Lex/Preprocessor.h?rev=119730&r1=119729&r2=119730&view=diff
==============================================================================
--- cfe/trunk/include/clang/Lex/Preprocessor.h (original)
+++ cfe/trunk/include/clang/Lex/Preprocessor.h Thu Nov 18 14:06:41 2010
@@ -626,12 +626,11 @@
   /// the specified Token's location, translating the token's start
   /// position in the current buffer into a SourcePosition object for rendering.
   DiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID) {
-    return Diags->Report(FullSourceLoc(Loc, getSourceManager()), DiagID);
+    return Diags->Report(Loc, DiagID);
   }
 
   DiagnosticBuilder Diag(const Token &Tok, unsigned DiagID) {
-    return Diags->Report(FullSourceLoc(Tok.getLocation(), getSourceManager()),
-                         DiagID);
+    return Diags->Report(Tok.getLocation(), DiagID);
   }
 
   /// getSpelling() - Return the 'spelling' of the Tok token.  The spelling of a

Modified: cfe/trunk/include/clang/Rewrite/FixItRewriter.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Rewrite/FixItRewriter.h?rev=119730&r1=119729&r2=119730&view=diff
==============================================================================
--- cfe/trunk/include/clang/Rewrite/FixItRewriter.h (original)
+++ cfe/trunk/include/clang/Rewrite/FixItRewriter.h Thu Nov 18 14:06:41 2010
@@ -99,7 +99,7 @@
                                 const DiagnosticInfo &Info);
 
   /// \brief Emit a diagnostic via the adapted diagnostic client.
-  void Diag(FullSourceLoc Loc, unsigned DiagID);
+  void Diag(SourceLocation Loc, unsigned DiagID);
 };
 
 }

Modified: cfe/trunk/lib/AST/ASTImporter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTImporter.cpp?rev=119730&r1=119729&r2=119730&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ASTImporter.cpp (original)
+++ cfe/trunk/lib/AST/ASTImporter.cpp Thu Nov 18 14:06:41 2010
@@ -137,9 +137,6 @@
     /// \brief AST contexts for which we are checking structural equivalence.
     ASTContext &C1, &C2;
     
-    /// \brief Diagnostic object used to emit diagnostics.
-    Diagnostic &Diags;
-    
     /// \brief The set of "tentative" equivalences between two canonical 
     /// declarations, mapping from a declaration in the first context to the
     /// declaration in the second context that we believe to be equivalent.
@@ -158,10 +155,9 @@
     bool StrictTypeSpelling;
     
     StructuralEquivalenceContext(ASTContext &C1, ASTContext &C2,
-                                 Diagnostic &Diags,
                llvm::DenseSet<std::pair<Decl *, Decl *> > &NonEquivalentDecls,
                                  bool StrictTypeSpelling = false)
-      : C1(C1), C2(C2), Diags(Diags), NonEquivalentDecls(NonEquivalentDecls),
+      : C1(C1), C2(C2), NonEquivalentDecls(NonEquivalentDecls),
         StrictTypeSpelling(StrictTypeSpelling) { }
 
     /// \brief Determine whether the two declarations are structurally
@@ -179,11 +175,11 @@
     
   public:
     DiagnosticBuilder Diag1(SourceLocation Loc, unsigned DiagID) {
-      return Diags.Report(FullSourceLoc(Loc, C1.getSourceManager()), DiagID);
+      return C1.getDiagnostics().Report(Loc, DiagID);
     }
 
     DiagnosticBuilder Diag2(SourceLocation Loc, unsigned DiagID) {
-      return Diags.Report(FullSourceLoc(Loc, C2.getSourceManager()), DiagID);
+      return C2.getDiagnostics().Report(Loc, DiagID);
     }
   };
 }
@@ -1432,7 +1428,6 @@
                                         RecordDecl *ToRecord) {
   StructuralEquivalenceContext Ctx(Importer.getFromContext(),
                                    Importer.getToContext(),
-                                   Importer.getDiags(),
                                    Importer.getNonEquivalentDecls());
   return Ctx.IsStructurallyEquivalent(FromRecord, ToRecord);
 }
@@ -1440,7 +1435,6 @@
 bool ASTNodeImporter::IsStructuralMatch(EnumDecl *FromEnum, EnumDecl *ToEnum) {
   StructuralEquivalenceContext Ctx(Importer.getFromContext(),
                                    Importer.getToContext(),
-                                   Importer.getDiags(),
                                    Importer.getNonEquivalentDecls());
   return Ctx.IsStructurallyEquivalent(FromEnum, ToEnum);
 }
@@ -2983,15 +2977,13 @@
                                 Importer.Import(E->getRParenLoc()));
 }
 
-ASTImporter::ASTImporter(Diagnostic &Diags,
-                         ASTContext &ToContext, FileManager &ToFileManager,
+ASTImporter::ASTImporter(ASTContext &ToContext, FileManager &ToFileManager,
                          const FileSystemOptions &ToFileSystemOpts,
                          ASTContext &FromContext, FileManager &FromFileManager,
                          const FileSystemOptions &FromFileSystemOpts)
   : ToContext(ToContext), FromContext(FromContext),
     ToFileManager(ToFileManager), FromFileManager(FromFileManager),
-    ToFileSystemOpts(ToFileSystemOpts), FromFileSystemOpts(FromFileSystemOpts),
-    Diags(Diags) {
+    ToFileSystemOpts(ToFileSystemOpts), FromFileSystemOpts(FromFileSystemOpts) {
   ImportedDecls[FromContext.getTranslationUnitDecl()]
     = ToContext.getTranslationUnitDecl();
 }
@@ -3167,7 +3159,8 @@
                              FromSLoc.getFile().getFileCharacteristic());
   } else {
     // FIXME: We want to re-use the existing MemoryBuffer!
-    const llvm::MemoryBuffer *FromBuf = Cache->getBuffer(getDiags(), FromSM);
+    const llvm::MemoryBuffer *
+        FromBuf = Cache->getBuffer(FromContext.getDiagnostics(), FromSM);
     llvm::MemoryBuffer *ToBuf
       = llvm::MemoryBuffer::getMemBufferCopy(FromBuf->getBuffer(),
                                              FromBuf->getBufferIdentifier());
@@ -3263,13 +3256,11 @@
 }
 
 DiagnosticBuilder ASTImporter::ToDiag(SourceLocation Loc, unsigned DiagID) {
-  return Diags.Report(FullSourceLoc(Loc, ToContext.getSourceManager()), 
-                      DiagID);
+  return ToContext.getDiagnostics().Report(Loc, DiagID);
 }
 
 DiagnosticBuilder ASTImporter::FromDiag(SourceLocation Loc, unsigned DiagID) {
-  return Diags.Report(FullSourceLoc(Loc, FromContext.getSourceManager()), 
-                      DiagID);
+  return FromContext.getDiagnostics().Report(Loc, DiagID);
 }
 
 Decl *ASTImporter::Imported(Decl *From, Decl *To) {
@@ -3283,7 +3274,6 @@
   if (Pos != ImportedTypes.end() && ToContext.hasSameType(Import(From), To))
     return true;
       
-  StructuralEquivalenceContext Ctx(FromContext, ToContext, Diags, 
-                                   NonEquivalentDecls);
+  StructuralEquivalenceContext Ctx(FromContext, ToContext, NonEquivalentDecls);
   return Ctx.IsStructurallyEquivalent(From, To);
 }

Modified: cfe/trunk/lib/AST/RecordLayoutBuilder.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/RecordLayoutBuilder.cpp?rev=119730&r1=119729&r2=119730&view=diff
==============================================================================
--- cfe/trunk/lib/AST/RecordLayoutBuilder.cpp (original)
+++ cfe/trunk/lib/AST/RecordLayoutBuilder.cpp Thu Nov 18 14:06:41 2010
@@ -1633,8 +1633,7 @@
 
 DiagnosticBuilder
 RecordLayoutBuilder::Diag(SourceLocation Loc, unsigned DiagID) {
-  return Context.getDiagnostics().Report(
-                        FullSourceLoc(Loc, Context.getSourceManager()), DiagID);
+  return Context.getDiagnostics().Report(Loc, DiagID);
 }
 
 namespace {

Modified: cfe/trunk/lib/Basic/Diagnostic.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Basic/Diagnostic.cpp?rev=119730&r1=119729&r2=119730&view=diff
==============================================================================
--- cfe/trunk/lib/Basic/Diagnostic.cpp (original)
+++ cfe/trunk/lib/Basic/Diagnostic.cpp Thu Nov 18 14:06:41 2010
@@ -11,227 +11,13 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "clang/AST/ASTDiagnostic.h"
-#include "clang/Analysis/AnalysisDiagnostic.h"
 #include "clang/Basic/Diagnostic.h"
-#include "clang/Basic/FileManager.h"
 #include "clang/Basic/IdentifierTable.h"
 #include "clang/Basic/PartialDiagnostic.h"
-#include "clang/Basic/SourceLocation.h"
-#include "clang/Basic/SourceManager.h"
-#include "clang/Driver/DriverDiagnostic.h"
-#include "clang/Frontend/FrontendDiagnostic.h"
-#include "clang/Lex/LexDiagnostic.h"
-#include "clang/Parse/ParseDiagnostic.h"
-#include "clang/Sema/SemaDiagnostic.h"
 #include "llvm/ADT/SmallVector.h"
-#include "llvm/ADT/StringExtras.h"
-#include "llvm/Support/MemoryBuffer.h"
 #include "llvm/Support/raw_ostream.h"
-
-#include <vector>
-#include <map>
-#include <cstring>
 using namespace clang;
 
-//===----------------------------------------------------------------------===//
-// Builtin Diagnostic information
-//===----------------------------------------------------------------------===//
-
-namespace {
-
-// Diagnostic classes.
-enum {
-  CLASS_NOTE       = 0x01,
-  CLASS_WARNING    = 0x02,
-  CLASS_EXTENSION  = 0x03,
-  CLASS_ERROR      = 0x04
-};
-
-struct StaticDiagInfoRec {
-  unsigned short DiagID;
-  unsigned Mapping : 3;
-  unsigned Class : 3;
-  bool SFINAE : 1;
-  unsigned Category : 5;
-  
-  const char *Description;
-  const char *OptionGroup;
-
-  bool operator<(const StaticDiagInfoRec &RHS) const {
-    return DiagID < RHS.DiagID;
-  }
-};
-
-}
-
-static const StaticDiagInfoRec StaticDiagInfo[] = {
-#define DIAG(ENUM,CLASS,DEFAULT_MAPPING,DESC,GROUP,SFINAE, CATEGORY)    \
-  { diag::ENUM, DEFAULT_MAPPING, CLASS, SFINAE, CATEGORY, DESC, GROUP },
-#include "clang/Basic/DiagnosticCommonKinds.inc"
-#include "clang/Basic/DiagnosticDriverKinds.inc"
-#include "clang/Basic/DiagnosticFrontendKinds.inc"
-#include "clang/Basic/DiagnosticLexKinds.inc"
-#include "clang/Basic/DiagnosticParseKinds.inc"
-#include "clang/Basic/DiagnosticASTKinds.inc"
-#include "clang/Basic/DiagnosticSemaKinds.inc"
-#include "clang/Basic/DiagnosticAnalysisKinds.inc"
-  { 0, 0, 0, 0, 0, 0, 0}
-};
-#undef DIAG
-
-/// GetDiagInfo - Return the StaticDiagInfoRec entry for the specified DiagID,
-/// or null if the ID is invalid.
-static const StaticDiagInfoRec *GetDiagInfo(unsigned DiagID) {
-  unsigned NumDiagEntries = sizeof(StaticDiagInfo)/sizeof(StaticDiagInfo[0])-1;
-
-  // If assertions are enabled, verify that the StaticDiagInfo array is sorted.
-#ifndef NDEBUG
-  static bool IsFirst = true;
-  if (IsFirst) {
-    for (unsigned i = 1; i != NumDiagEntries; ++i) {
-      assert(StaticDiagInfo[i-1].DiagID != StaticDiagInfo[i].DiagID &&
-             "Diag ID conflict, the enums at the start of clang::diag (in "
-             "Diagnostic.h) probably need to be increased");
-
-      assert(StaticDiagInfo[i-1] < StaticDiagInfo[i] &&
-             "Improperly sorted diag info");
-    }
-    IsFirst = false;
-  }
-#endif
-
-  // Search the diagnostic table with a binary search.
-  StaticDiagInfoRec Find = { DiagID, 0, 0, 0, 0, 0, 0 };
-
-  const StaticDiagInfoRec *Found =
-    std::lower_bound(StaticDiagInfo, StaticDiagInfo + NumDiagEntries, Find);
-  if (Found == StaticDiagInfo + NumDiagEntries ||
-      Found->DiagID != DiagID)
-    return 0;
-
-  return Found;
-}
-
-static unsigned GetDefaultDiagMapping(unsigned DiagID) {
-  if (const StaticDiagInfoRec *Info = GetDiagInfo(DiagID))
-    return Info->Mapping;
-  return diag::MAP_FATAL;
-}
-
-/// getWarningOptionForDiag - Return the lowest-level warning option that
-/// enables the specified diagnostic.  If there is no -Wfoo flag that controls
-/// the diagnostic, this returns null.
-const char *Diagnostic::getWarningOptionForDiag(unsigned DiagID) {
-  if (const StaticDiagInfoRec *Info = GetDiagInfo(DiagID))
-    return Info->OptionGroup;
-  return 0;
-}
-
-/// getWarningOptionForDiag - Return the category number that a specified
-/// DiagID belongs to, or 0 if no category.
-unsigned Diagnostic::getCategoryNumberForDiag(unsigned DiagID) {
-  if (const StaticDiagInfoRec *Info = GetDiagInfo(DiagID))
-    return Info->Category;
-  return 0;
-}
-
-/// getCategoryNameFromID - Given a category ID, return the name of the
-/// category, an empty string if CategoryID is zero, or null if CategoryID is
-/// invalid.
-const char *Diagnostic::getCategoryNameFromID(unsigned CategoryID) {
-  // Second the table of options, sorted by name for fast binary lookup.
-  static const char *CategoryNameTable[] = {
-#define GET_CATEGORY_TABLE
-#define CATEGORY(X) X,
-#include "clang/Basic/DiagnosticGroups.inc"
-#undef GET_CATEGORY_TABLE
-    "<<END>>"
-  };
-  static const size_t CategoryNameTableSize =
-    sizeof(CategoryNameTable) / sizeof(CategoryNameTable[0])-1;
-  
-  if (CategoryID >= CategoryNameTableSize) return 0;
-  return CategoryNameTable[CategoryID];
-}
-
-
-
-Diagnostic::SFINAEResponse 
-Diagnostic::getDiagnosticSFINAEResponse(unsigned DiagID) {
-  if (const StaticDiagInfoRec *Info = GetDiagInfo(DiagID)) {
-    if (!Info->SFINAE)
-      return SFINAE_Report;
-
-    if (Info->Class == CLASS_ERROR)
-      return SFINAE_SubstitutionFailure;
-    
-    // Suppress notes, warnings, and extensions;
-    return SFINAE_Suppress;
-  }
-  
-  return SFINAE_Report;
-}
-
-/// getDiagClass - Return the class field of the diagnostic.
-///
-static unsigned getBuiltinDiagClass(unsigned DiagID) {
-  if (const StaticDiagInfoRec *Info = GetDiagInfo(DiagID))
-    return Info->Class;
-  return ~0U;
-}
-
-//===----------------------------------------------------------------------===//
-// Custom Diagnostic information
-//===----------------------------------------------------------------------===//
-
-namespace clang {
-  namespace diag {
-    class CustomDiagInfo {
-      typedef std::pair<Diagnostic::Level, std::string> DiagDesc;
-      std::vector<DiagDesc> DiagInfo;
-      std::map<DiagDesc, unsigned> DiagIDs;
-    public:
-
-      /// getDescription - Return the description of the specified custom
-      /// diagnostic.
-      const char *getDescription(unsigned DiagID) const {
-        assert(this && DiagID-DIAG_UPPER_LIMIT < DiagInfo.size() &&
-               "Invalid diagnosic ID");
-        return DiagInfo[DiagID-DIAG_UPPER_LIMIT].second.c_str();
-      }
-
-      /// getLevel - Return the level of the specified custom diagnostic.
-      Diagnostic::Level getLevel(unsigned DiagID) const {
-        assert(this && DiagID-DIAG_UPPER_LIMIT < DiagInfo.size() &&
-               "Invalid diagnosic ID");
-        return DiagInfo[DiagID-DIAG_UPPER_LIMIT].first;
-      }
-
-      unsigned getOrCreateDiagID(Diagnostic::Level L, llvm::StringRef Message,
-                                 Diagnostic &Diags) {
-        DiagDesc D(L, Message);
-        // Check to see if it already exists.
-        std::map<DiagDesc, unsigned>::iterator I = DiagIDs.lower_bound(D);
-        if (I != DiagIDs.end() && I->first == D)
-          return I->second;
-
-        // If not, assign a new ID.
-        unsigned ID = DiagInfo.size()+DIAG_UPPER_LIMIT;
-        DiagIDs.insert(std::make_pair(D, ID));
-        DiagInfo.push_back(D);
-        return ID;
-      }
-    };
-
-  } // end diag namespace
-} // end clang namespace
-
-
-//===----------------------------------------------------------------------===//
-// Common Diagnostic implementation
-//===----------------------------------------------------------------------===//
-
 static void DummyArgToStringFn(Diagnostic::ArgumentKind AK, intptr_t QT,
                                const char *Modifier, unsigned ML,
                                const char *Argument, unsigned ArgLen,
@@ -244,7 +30,10 @@
 }
 
 
-Diagnostic::Diagnostic(DiagnosticClient *client) : Client(client) {
+Diagnostic::Diagnostic(const llvm::IntrusiveRefCntPtr<DiagnosticIDs> &diags,
+                       DiagnosticClient *client, bool ShouldOwnClient)
+  : Diags(diags), Client(client), OwnsDiagClient(ShouldOwnClient),
+    SourceMgr(0) {
   ArgToStringFn = DummyArgToStringFn;
   ArgToStringCookie = 0;
 
@@ -259,7 +48,6 @@
 
   ErrorLimit = 0;
   TemplateBacktraceLimit = 0;
-  CustomDiagInfo = 0;
 
   // Set all mappings to 'unset'.
   DiagMappingsStack.clear();
@@ -269,7 +57,8 @@
 }
 
 Diagnostic::~Diagnostic() {
-  delete CustomDiagInfo;
+  if (OwnsDiagClient)
+    delete Client;
 }
 
 
@@ -287,47 +76,6 @@
   return true;
 }
 
-/// getCustomDiagID - Return an ID for a diagnostic with the specified message
-/// and level.  If this is the first request for this diagnosic, it is
-/// registered and created, otherwise the existing ID is returned.
-unsigned Diagnostic::getCustomDiagID(Level L, llvm::StringRef Message) {
-  if (CustomDiagInfo == 0)
-    CustomDiagInfo = new diag::CustomDiagInfo();
-  return CustomDiagInfo->getOrCreateDiagID(L, Message, *this);
-}
-
-
-/// isBuiltinWarningOrExtension - Return true if the unmapped diagnostic
-/// level of the specified diagnostic ID is a Warning or Extension.
-/// This only works on builtin diagnostics, not custom ones, and is not legal to
-/// call on NOTEs.
-bool Diagnostic::isBuiltinWarningOrExtension(unsigned DiagID) {
-  return DiagID < diag::DIAG_UPPER_LIMIT &&
-         getBuiltinDiagClass(DiagID) != CLASS_ERROR;
-}
-
-/// \brief Determine whether the given built-in diagnostic ID is a
-/// Note.
-bool Diagnostic::isBuiltinNote(unsigned DiagID) {
-  return DiagID < diag::DIAG_UPPER_LIMIT &&
-    getBuiltinDiagClass(DiagID) == CLASS_NOTE;
-}
-
-/// isBuiltinExtensionDiag - Determine whether the given built-in diagnostic
-/// ID is for an extension of some sort.  This also returns EnabledByDefault,
-/// which is set to indicate whether the diagnostic is ignored by default (in
-/// which case -pedantic enables it) or treated as a warning/error by default.
-///
-bool Diagnostic::isBuiltinExtensionDiag(unsigned DiagID,
-                                        bool &EnabledByDefault) {
-  if (DiagID >= diag::DIAG_UPPER_LIMIT ||
-      getBuiltinDiagClass(DiagID) != CLASS_EXTENSION)
-    return false;
-  
-  EnabledByDefault = GetDefaultDiagMapping(DiagID) != diag::MAP_IGNORE;
-  return true;
-}
-
 void Diagnostic::Reset() {
   ErrorOccurred = false;
   FatalErrorOccurred = false;
@@ -336,18 +84,14 @@
   NumErrors = 0;
   NumErrorsSuppressed = 0;
   CurDiagID = ~0U;
-  LastDiagLevel = Ignored;
+  // Set LastDiagLevel to an "unset" state. If we set it to 'Ignored', notes
+  // using a Diagnostic associated to a translation unit that follow
+  // diagnostics from a Diagnostic associated to anoter t.u. will not be
+  // displayed.
+  LastDiagLevel = (DiagnosticIDs::Level)-1;
   DelayedDiagID = 0;
 }
 
-/// getDescription - Given a diagnostic ID, return a description of the
-/// issue.
-const char *Diagnostic::getDescription(unsigned DiagID) const {
-  if (const StaticDiagInfoRec *Info = GetDiagInfo(DiagID))
-    return Info->Description;
-  return CustomDiagInfo->getDescription(DiagID);
-}
-
 void Diagnostic::SetDelayedDiagnostic(unsigned DiagID, llvm::StringRef Arg1,
                                       llvm::StringRef Arg2) {
   if (DelayedDiagID)
@@ -365,266 +109,6 @@
   DelayedDiagArg2.clear();
 }
 
-/// getDiagnosticLevel - Based on the way the client configured the Diagnostic
-/// object, classify the specified diagnostic ID into a Level, consumable by
-/// the DiagnosticClient.
-Diagnostic::Level Diagnostic::getDiagnosticLevel(unsigned DiagID) const {
-  // Handle custom diagnostics, which cannot be mapped.
-  if (DiagID >= diag::DIAG_UPPER_LIMIT)
-    return CustomDiagInfo->getLevel(DiagID);
-
-  unsigned DiagClass = getBuiltinDiagClass(DiagID);
-  assert(DiagClass != CLASS_NOTE && "Cannot get diagnostic level of a note!");
-  return getDiagnosticLevel(DiagID, DiagClass);
-}
-
-/// getDiagnosticLevel - Based on the way the client configured the Diagnostic
-/// object, classify the specified diagnostic ID into a Level, consumable by
-/// the DiagnosticClient.
-Diagnostic::Level
-Diagnostic::getDiagnosticLevel(unsigned DiagID, unsigned DiagClass) const {
-  // Specific non-error diagnostics may be mapped to various levels from ignored
-  // to error.  Errors can only be mapped to fatal.
-  Diagnostic::Level Result = Diagnostic::Fatal;
-
-  // Get the mapping information, if unset, compute it lazily.
-  unsigned MappingInfo = getDiagnosticMappingInfo((diag::kind)DiagID);
-  if (MappingInfo == 0) {
-    MappingInfo = GetDefaultDiagMapping(DiagID);
-    setDiagnosticMappingInternal(DiagID, MappingInfo, false);
-  }
-
-  switch (MappingInfo & 7) {
-  default: assert(0 && "Unknown mapping!");
-  case diag::MAP_IGNORE:
-    // Ignore this, unless this is an extension diagnostic and we're mapping
-    // them onto warnings or errors.
-    if (!isBuiltinExtensionDiag(DiagID) ||  // Not an extension
-        ExtBehavior == Ext_Ignore ||        // Extensions ignored anyway
-        (MappingInfo & 8) != 0)             // User explicitly mapped it.
-      return Diagnostic::Ignored;
-    Result = Diagnostic::Warning;
-    if (ExtBehavior == Ext_Error) Result = Diagnostic::Error;
-    if (Result == Diagnostic::Error && ErrorsAsFatal)
-      Result = Diagnostic::Fatal;
-    break;
-  case diag::MAP_ERROR:
-    Result = Diagnostic::Error;
-    if (ErrorsAsFatal)
-      Result = Diagnostic::Fatal;
-    break;
-  case diag::MAP_FATAL:
-    Result = Diagnostic::Fatal;
-    break;
-  case diag::MAP_WARNING:
-    // If warnings are globally mapped to ignore or error, do it.
-    if (IgnoreAllWarnings)
-      return Diagnostic::Ignored;
-
-    Result = Diagnostic::Warning;
-
-    // If this is an extension diagnostic and we're in -pedantic-error mode, and
-    // if the user didn't explicitly map it, upgrade to an error.
-    if (ExtBehavior == Ext_Error &&
-        (MappingInfo & 8) == 0 &&
-        isBuiltinExtensionDiag(DiagID))
-      Result = Diagnostic::Error;
-
-    if (WarningsAsErrors)
-      Result = Diagnostic::Error;
-    if (Result == Diagnostic::Error && ErrorsAsFatal)
-      Result = Diagnostic::Fatal;
-    break;
-
-  case diag::MAP_WARNING_NO_WERROR:
-    // Diagnostics specified with -Wno-error=foo should be set to warnings, but
-    // not be adjusted by -Werror or -pedantic-errors.
-    Result = Diagnostic::Warning;
-
-    // If warnings are globally mapped to ignore or error, do it.
-    if (IgnoreAllWarnings)
-      return Diagnostic::Ignored;
-
-    break;
-
-  case diag::MAP_ERROR_NO_WFATAL:
-    // Diagnostics specified as -Wno-fatal-error=foo should be errors, but
-    // unaffected by -Wfatal-errors.
-    Result = Diagnostic::Error;
-    break;
-  }
-
-  // Okay, we're about to return this as a "diagnostic to emit" one last check:
-  // if this is any sort of extension warning, and if we're in an __extension__
-  // block, silence it.
-  if (AllExtensionsSilenced && isBuiltinExtensionDiag(DiagID))
-    return Diagnostic::Ignored;
-
-  return Result;
-}
-
-struct WarningOption {
-  const char  *Name;
-  const short *Members;
-  const short *SubGroups;
-};
-
-#define GET_DIAG_ARRAYS
-#include "clang/Basic/DiagnosticGroups.inc"
-#undef GET_DIAG_ARRAYS
-
-// Second the table of options, sorted by name for fast binary lookup.
-static const WarningOption OptionTable[] = {
-#define GET_DIAG_TABLE
-#include "clang/Basic/DiagnosticGroups.inc"
-#undef GET_DIAG_TABLE
-};
-static const size_t OptionTableSize =
-sizeof(OptionTable) / sizeof(OptionTable[0]);
-
-static bool WarningOptionCompare(const WarningOption &LHS,
-                                 const WarningOption &RHS) {
-  return strcmp(LHS.Name, RHS.Name) < 0;
-}
-
-static void MapGroupMembers(const WarningOption *Group, diag::Mapping Mapping,
-                            Diagnostic &Diags) {
-  // Option exists, poke all the members of its diagnostic set.
-  if (const short *Member = Group->Members) {
-    for (; *Member != -1; ++Member)
-      Diags.setDiagnosticMapping(*Member, Mapping);
-  }
-
-  // Enable/disable all subgroups along with this one.
-  if (const short *SubGroups = Group->SubGroups) {
-    for (; *SubGroups != (short)-1; ++SubGroups)
-      MapGroupMembers(&OptionTable[(short)*SubGroups], Mapping, Diags);
-  }
-}
-
-/// setDiagnosticGroupMapping - Change an entire diagnostic group (e.g.
-/// "unknown-pragmas" to have the specified mapping.  This returns true and
-/// ignores the request if "Group" was unknown, false otherwise.
-bool Diagnostic::setDiagnosticGroupMapping(const char *Group,
-                                           diag::Mapping Map) {
-
-  WarningOption Key = { Group, 0, 0 };
-  const WarningOption *Found =
-  std::lower_bound(OptionTable, OptionTable + OptionTableSize, Key,
-                   WarningOptionCompare);
-  if (Found == OptionTable + OptionTableSize ||
-      strcmp(Found->Name, Group) != 0)
-    return true;  // Option not found.
-
-  MapGroupMembers(Found, Map, *this);
-  return false;
-}
-
-
-/// ProcessDiag - This is the method used to report a diagnostic that is
-/// finally fully formed.
-bool Diagnostic::ProcessDiag() {
-  DiagnosticInfo Info(this);
-
-  if (SuppressAllDiagnostics)
-    return false;
-  
-  // Figure out the diagnostic level of this message.
-  Diagnostic::Level DiagLevel;
-  unsigned DiagID = Info.getID();
-
-  // ShouldEmitInSystemHeader - True if this diagnostic should be produced even
-  // in a system header.
-  bool ShouldEmitInSystemHeader;
-
-  if (DiagID >= diag::DIAG_UPPER_LIMIT) {
-    // Handle custom diagnostics, which cannot be mapped.
-    DiagLevel = CustomDiagInfo->getLevel(DiagID);
-
-    // Custom diagnostics always are emitted in system headers.
-    ShouldEmitInSystemHeader = true;
-  } else {
-    // Get the class of the diagnostic.  If this is a NOTE, map it onto whatever
-    // the diagnostic level was for the previous diagnostic so that it is
-    // filtered the same as the previous diagnostic.
-    unsigned DiagClass = getBuiltinDiagClass(DiagID);
-    if (DiagClass == CLASS_NOTE) {
-      DiagLevel = Diagnostic::Note;
-      ShouldEmitInSystemHeader = false;  // extra consideration is needed
-    } else {
-      // If this is not an error and we are in a system header, we ignore it.
-      // Check the original Diag ID here, because we also want to ignore
-      // extensions and warnings in -Werror and -pedantic-errors modes, which
-      // *map* warnings/extensions to errors.
-      ShouldEmitInSystemHeader = DiagClass == CLASS_ERROR;
-
-      DiagLevel = getDiagnosticLevel(DiagID, DiagClass);
-    }
-  }
-
-  if (DiagLevel != Diagnostic::Note) {
-    // Record that a fatal error occurred only when we see a second
-    // non-note diagnostic. This allows notes to be attached to the
-    // fatal error, but suppresses any diagnostics that follow those
-    // notes.
-    if (LastDiagLevel == Diagnostic::Fatal)
-      FatalErrorOccurred = true;
-
-    LastDiagLevel = DiagLevel;
-  }
-
-  // If a fatal error has already been emitted, silence all subsequent
-  // diagnostics.
-  if (FatalErrorOccurred) {
-    if (DiagLevel >= Diagnostic::Error && Client->IncludeInDiagnosticCounts()) {
-      ++NumErrors;
-      ++NumErrorsSuppressed;
-    }
-
-    return false;
-  }
-
-  // If the client doesn't care about this message, don't issue it.  If this is
-  // a note and the last real diagnostic was ignored, ignore it too.
-  if (DiagLevel == Diagnostic::Ignored ||
-      (DiagLevel == Diagnostic::Note && LastDiagLevel == Diagnostic::Ignored))
-    return false;
-
-  // If this diagnostic is in a system header and is not a clang error, suppress
-  // it.
-  if (SuppressSystemWarnings && !ShouldEmitInSystemHeader &&
-      Info.getLocation().isValid() &&
-      Info.getLocation().getInstantiationLoc().isInSystemHeader() &&
-      (DiagLevel != Diagnostic::Note || LastDiagLevel == Diagnostic::Ignored)) {
-    LastDiagLevel = Diagnostic::Ignored;
-    return false;
-  }
-
-  if (DiagLevel >= Diagnostic::Error) {
-    if (Client->IncludeInDiagnosticCounts()) {
-      ErrorOccurred = true;
-      ++NumErrors;
-    }
-
-    // If we've emitted a lot of errors, emit a fatal error after it to stop a
-    // flood of bogus errors.
-    if (ErrorLimit && NumErrors >= ErrorLimit &&
-        DiagLevel == Diagnostic::Error)
-      SetDelayedDiagnostic(diag::fatal_too_many_errors);
-  }
-
-  // Finally, report it.
-  Client->HandleDiagnostic(DiagLevel, Info);
-  if (Client->IncludeInDiagnosticCounts()) {
-    if (DiagLevel == Diagnostic::Warning)
-      ++NumWarnings;
-  }
-
-  CurDiagID = ~0U;
-
-  return true;
-}
-
 void DiagnosticBuilder::FlushCounts() {
   DiagObj->NumDiagArgs = NumArgs;
   DiagObj->NumDiagRanges = NumRanges;
@@ -889,7 +373,7 @@
 /// array.
 void DiagnosticInfo::
 FormatDiagnostic(llvm::SmallVectorImpl<char> &OutStr) const {
-  const char *DiagStr = getDiags()->getDescription(getID());
+  const char *DiagStr = getDiags()->getDiagnosticIDs()->getDescription(getID());
   const char *DiagEnd = DiagStr+strlen(DiagStr);
 
   FormatDiagnostic(DiagStr, DiagEnd, OutStr);
@@ -1059,7 +543,11 @@
 
 StoredDiagnostic::StoredDiagnostic(Diagnostic::Level Level, 
                                    const DiagnosticInfo &Info)
-  : Level(Level), Loc(Info.getLocation()) {
+  : Level(Level) {
+  assert((Info.getLocation().isInvalid() || Info.hasSourceManager()) &&
+       "Valid source location without setting a source manager for diagnostic");
+  if (Info.getLocation().isValid())
+    Loc = FullSourceLoc(Info.getLocation(), Info.getSourceManager());
   llvm::SmallString<64> Message;
   Info.FormatDiagnostic(Message);
   this->Message.assign(Message.begin(), Message.end());

Added: cfe/trunk/lib/Basic/DiagnosticIDs.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Basic/DiagnosticIDs.cpp?rev=119730&view=auto
==============================================================================
--- cfe/trunk/lib/Basic/DiagnosticIDs.cpp (added)
+++ cfe/trunk/lib/Basic/DiagnosticIDs.cpp Thu Nov 18 14:06:41 2010
@@ -0,0 +1,547 @@
+//===--- DiagnosticIDs.cpp - Diagnostic IDs Handling ----------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file implements the Diagnostic IDs-related interfaces.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/AST/ASTDiagnostic.h"
+#include "clang/Analysis/AnalysisDiagnostic.h"
+#include "clang/Basic/DiagnosticIDs.h"
+#include "clang/Basic/SourceManager.h"
+#include "clang/Driver/DriverDiagnostic.h"
+#include "clang/Frontend/FrontendDiagnostic.h"
+#include "clang/Lex/LexDiagnostic.h"
+#include "clang/Parse/ParseDiagnostic.h"
+#include "clang/Sema/SemaDiagnostic.h"
+
+#include <map>
+using namespace clang;
+
+//===----------------------------------------------------------------------===//
+// Builtin Diagnostic information
+//===----------------------------------------------------------------------===//
+
+namespace {
+
+// Diagnostic classes.
+enum {
+  CLASS_NOTE       = 0x01,
+  CLASS_WARNING    = 0x02,
+  CLASS_EXTENSION  = 0x03,
+  CLASS_ERROR      = 0x04
+};
+
+struct StaticDiagInfoRec {
+  unsigned short DiagID;
+  unsigned Mapping : 3;
+  unsigned Class : 3;
+  bool SFINAE : 1;
+  unsigned Category : 5;
+  
+  const char *Description;
+  const char *OptionGroup;
+
+  bool operator<(const StaticDiagInfoRec &RHS) const {
+    return DiagID < RHS.DiagID;
+  }
+};
+
+}
+
+static const StaticDiagInfoRec StaticDiagInfo[] = {
+#define DIAG(ENUM,CLASS,DEFAULT_MAPPING,DESC,GROUP,SFINAE, CATEGORY)    \
+  { diag::ENUM, DEFAULT_MAPPING, CLASS, SFINAE, CATEGORY, DESC, GROUP },
+#include "clang/Basic/DiagnosticCommonKinds.inc"
+#include "clang/Basic/DiagnosticDriverKinds.inc"
+#include "clang/Basic/DiagnosticFrontendKinds.inc"
+#include "clang/Basic/DiagnosticLexKinds.inc"
+#include "clang/Basic/DiagnosticParseKinds.inc"
+#include "clang/Basic/DiagnosticASTKinds.inc"
+#include "clang/Basic/DiagnosticSemaKinds.inc"
+#include "clang/Basic/DiagnosticAnalysisKinds.inc"
+  { 0, 0, 0, 0, 0, 0, 0}
+};
+#undef DIAG
+
+/// GetDiagInfo - Return the StaticDiagInfoRec entry for the specified DiagID,
+/// or null if the ID is invalid.
+static const StaticDiagInfoRec *GetDiagInfo(unsigned DiagID) {
+  unsigned NumDiagEntries = sizeof(StaticDiagInfo)/sizeof(StaticDiagInfo[0])-1;
+
+  // If assertions are enabled, verify that the StaticDiagInfo array is sorted.
+#ifndef NDEBUG
+  static bool IsFirst = true;
+  if (IsFirst) {
+    for (unsigned i = 1; i != NumDiagEntries; ++i) {
+      assert(StaticDiagInfo[i-1].DiagID != StaticDiagInfo[i].DiagID &&
+             "Diag ID conflict, the enums at the start of clang::diag (in "
+             "Diagnostic.h) probably need to be increased");
+
+      assert(StaticDiagInfo[i-1] < StaticDiagInfo[i] &&
+             "Improperly sorted diag info");
+    }
+    IsFirst = false;
+  }
+#endif
+
+  // Search the diagnostic table with a binary search.
+  StaticDiagInfoRec Find = { DiagID, 0, 0, 0, 0, 0, 0 };
+
+  const StaticDiagInfoRec *Found =
+    std::lower_bound(StaticDiagInfo, StaticDiagInfo + NumDiagEntries, Find);
+  if (Found == StaticDiagInfo + NumDiagEntries ||
+      Found->DiagID != DiagID)
+    return 0;
+
+  return Found;
+}
+
+static unsigned GetDefaultDiagMapping(unsigned DiagID) {
+  if (const StaticDiagInfoRec *Info = GetDiagInfo(DiagID))
+    return Info->Mapping;
+  return diag::MAP_FATAL;
+}
+
+/// getWarningOptionForDiag - Return the lowest-level warning option that
+/// enables the specified diagnostic.  If there is no -Wfoo flag that controls
+/// the diagnostic, this returns null.
+const char *DiagnosticIDs::getWarningOptionForDiag(unsigned DiagID) {
+  if (const StaticDiagInfoRec *Info = GetDiagInfo(DiagID))
+    return Info->OptionGroup;
+  return 0;
+}
+
+/// getWarningOptionForDiag - Return the category number that a specified
+/// DiagID belongs to, or 0 if no category.
+unsigned DiagnosticIDs::getCategoryNumberForDiag(unsigned DiagID) {
+  if (const StaticDiagInfoRec *Info = GetDiagInfo(DiagID))
+    return Info->Category;
+  return 0;
+}
+
+/// getCategoryNameFromID - Given a category ID, return the name of the
+/// category, an empty string if CategoryID is zero, or null if CategoryID is
+/// invalid.
+const char *DiagnosticIDs::getCategoryNameFromID(unsigned CategoryID) {
+  // Second the table of options, sorted by name for fast binary lookup.
+  static const char *CategoryNameTable[] = {
+#define GET_CATEGORY_TABLE
+#define CATEGORY(X) X,
+#include "clang/Basic/DiagnosticGroups.inc"
+#undef GET_CATEGORY_TABLE
+    "<<END>>"
+  };
+  static const size_t CategoryNameTableSize =
+    sizeof(CategoryNameTable) / sizeof(CategoryNameTable[0])-1;
+  
+  if (CategoryID >= CategoryNameTableSize) return 0;
+  return CategoryNameTable[CategoryID];
+}
+
+
+
+DiagnosticIDs::SFINAEResponse 
+DiagnosticIDs::getDiagnosticSFINAEResponse(unsigned DiagID) {
+  if (const StaticDiagInfoRec *Info = GetDiagInfo(DiagID)) {
+    if (!Info->SFINAE)
+      return SFINAE_Report;
+
+    if (Info->Class == CLASS_ERROR)
+      return SFINAE_SubstitutionFailure;
+    
+    // Suppress notes, warnings, and extensions;
+    return SFINAE_Suppress;
+  }
+  
+  return SFINAE_Report;
+}
+
+/// getDiagClass - Return the class field of the diagnostic.
+///
+static unsigned getBuiltinDiagClass(unsigned DiagID) {
+  if (const StaticDiagInfoRec *Info = GetDiagInfo(DiagID))
+    return Info->Class;
+  return ~0U;
+}
+
+//===----------------------------------------------------------------------===//
+// Custom Diagnostic information
+//===----------------------------------------------------------------------===//
+
+namespace clang {
+  namespace diag {
+    class CustomDiagInfo {
+      typedef std::pair<DiagnosticIDs::Level, std::string> DiagDesc;
+      std::vector<DiagDesc> DiagInfo;
+      std::map<DiagDesc, unsigned> DiagIDs;
+    public:
+
+      /// getDescription - Return the description of the specified custom
+      /// diagnostic.
+      const char *getDescription(unsigned DiagID) const {
+        assert(this && DiagID-DIAG_UPPER_LIMIT < DiagInfo.size() &&
+               "Invalid diagnosic ID");
+        return DiagInfo[DiagID-DIAG_UPPER_LIMIT].second.c_str();
+      }
+
+      /// getLevel - Return the level of the specified custom diagnostic.
+      DiagnosticIDs::Level getLevel(unsigned DiagID) const {
+        assert(this && DiagID-DIAG_UPPER_LIMIT < DiagInfo.size() &&
+               "Invalid diagnosic ID");
+        return DiagInfo[DiagID-DIAG_UPPER_LIMIT].first;
+      }
+
+      unsigned getOrCreateDiagID(DiagnosticIDs::Level L, llvm::StringRef Message,
+                                 DiagnosticIDs &Diags) {
+        DiagDesc D(L, Message);
+        // Check to see if it already exists.
+        std::map<DiagDesc, unsigned>::iterator I = DiagIDs.lower_bound(D);
+        if (I != DiagIDs.end() && I->first == D)
+          return I->second;
+
+        // If not, assign a new ID.
+        unsigned ID = DiagInfo.size()+DIAG_UPPER_LIMIT;
+        DiagIDs.insert(std::make_pair(D, ID));
+        DiagInfo.push_back(D);
+        return ID;
+      }
+    };
+
+  } // end diag namespace
+} // end clang namespace
+
+
+//===----------------------------------------------------------------------===//
+// Common Diagnostic implementation
+//===----------------------------------------------------------------------===//
+
+DiagnosticIDs::DiagnosticIDs() {
+  CustomDiagInfo = 0;
+}
+
+DiagnosticIDs::~DiagnosticIDs() {
+  delete CustomDiagInfo;
+}
+
+/// getCustomDiagID - Return an ID for a diagnostic with the specified message
+/// and level.  If this is the first request for this diagnosic, it is
+/// registered and created, otherwise the existing ID is returned.
+unsigned DiagnosticIDs::getCustomDiagID(Level L, llvm::StringRef Message) {
+  if (CustomDiagInfo == 0)
+    CustomDiagInfo = new diag::CustomDiagInfo();
+  return CustomDiagInfo->getOrCreateDiagID(L, Message, *this);
+}
+
+
+/// isBuiltinWarningOrExtension - Return true if the unmapped diagnostic
+/// level of the specified diagnostic ID is a Warning or Extension.
+/// This only works on builtin diagnostics, not custom ones, and is not legal to
+/// call on NOTEs.
+bool DiagnosticIDs::isBuiltinWarningOrExtension(unsigned DiagID) {
+  return DiagID < diag::DIAG_UPPER_LIMIT &&
+         getBuiltinDiagClass(DiagID) != CLASS_ERROR;
+}
+
+/// \brief Determine whether the given built-in diagnostic ID is a
+/// Note.
+bool DiagnosticIDs::isBuiltinNote(unsigned DiagID) {
+  return DiagID < diag::DIAG_UPPER_LIMIT &&
+    getBuiltinDiagClass(DiagID) == CLASS_NOTE;
+}
+
+/// isBuiltinExtensionDiag - Determine whether the given built-in diagnostic
+/// ID is for an extension of some sort.  This also returns EnabledByDefault,
+/// which is set to indicate whether the diagnostic is ignored by default (in
+/// which case -pedantic enables it) or treated as a warning/error by default.
+///
+bool DiagnosticIDs::isBuiltinExtensionDiag(unsigned DiagID,
+                                        bool &EnabledByDefault) {
+  if (DiagID >= diag::DIAG_UPPER_LIMIT ||
+      getBuiltinDiagClass(DiagID) != CLASS_EXTENSION)
+    return false;
+  
+  EnabledByDefault = GetDefaultDiagMapping(DiagID) != diag::MAP_IGNORE;
+  return true;
+}
+
+/// getDescription - Given a diagnostic ID, return a description of the
+/// issue.
+const char *DiagnosticIDs::getDescription(unsigned DiagID) const {
+  if (const StaticDiagInfoRec *Info = GetDiagInfo(DiagID))
+    return Info->Description;
+  return CustomDiagInfo->getDescription(DiagID);
+}
+
+/// getDiagnosticLevel - Based on the way the client configured the Diagnostic
+/// object, classify the specified diagnostic ID into a Level, consumable by
+/// the DiagnosticClient.
+DiagnosticIDs::Level DiagnosticIDs::getDiagnosticLevel(unsigned DiagID,
+                                        const Diagnostic &Diag) const {
+  // Handle custom diagnostics, which cannot be mapped.
+  if (DiagID >= diag::DIAG_UPPER_LIMIT)
+    return CustomDiagInfo->getLevel(DiagID);
+
+  unsigned DiagClass = getBuiltinDiagClass(DiagID);
+  assert(DiagClass != CLASS_NOTE && "Cannot get diagnostic level of a note!");
+  return getDiagnosticLevel(DiagID, DiagClass, Diag);
+}
+
+/// getDiagnosticLevel - Based on the way the client configured the Diagnostic
+/// object, classify the specified diagnostic ID into a Level, consumable by
+/// the DiagnosticClient.
+DiagnosticIDs::Level
+DiagnosticIDs::getDiagnosticLevel(unsigned DiagID, unsigned DiagClass,
+                               const Diagnostic &Diag) const {
+  // Specific non-error diagnostics may be mapped to various levels from ignored
+  // to error.  Errors can only be mapped to fatal.
+  DiagnosticIDs::Level Result = DiagnosticIDs::Fatal;
+
+  // Get the mapping information, if unset, compute it lazily.
+  unsigned MappingInfo = Diag.getDiagnosticMappingInfo((diag::kind)DiagID);
+  if (MappingInfo == 0) {
+    MappingInfo = GetDefaultDiagMapping(DiagID);
+    Diag.setDiagnosticMappingInternal(DiagID, MappingInfo, false);
+  }
+
+  switch (MappingInfo & 7) {
+  default: assert(0 && "Unknown mapping!");
+  case diag::MAP_IGNORE:
+    // Ignore this, unless this is an extension diagnostic and we're mapping
+    // them onto warnings or errors.
+    if (!isBuiltinExtensionDiag(DiagID) ||  // Not an extension
+        Diag.ExtBehavior == Diagnostic::Ext_Ignore || // Ext ignored
+        (MappingInfo & 8) != 0)             // User explicitly mapped it.
+      return DiagnosticIDs::Ignored;
+    Result = DiagnosticIDs::Warning;
+    if (Diag.ExtBehavior == Diagnostic::Ext_Error) Result = DiagnosticIDs::Error;
+    if (Result == DiagnosticIDs::Error && Diag.ErrorsAsFatal)
+      Result = DiagnosticIDs::Fatal;
+    break;
+  case diag::MAP_ERROR:
+    Result = DiagnosticIDs::Error;
+    if (Diag.ErrorsAsFatal)
+      Result = DiagnosticIDs::Fatal;
+    break;
+  case diag::MAP_FATAL:
+    Result = DiagnosticIDs::Fatal;
+    break;
+  case diag::MAP_WARNING:
+    // If warnings are globally mapped to ignore or error, do it.
+    if (Diag.IgnoreAllWarnings)
+      return DiagnosticIDs::Ignored;
+
+    Result = DiagnosticIDs::Warning;
+
+    // If this is an extension diagnostic and we're in -pedantic-error mode, and
+    // if the user didn't explicitly map it, upgrade to an error.
+    if (Diag.ExtBehavior == Diagnostic::Ext_Error &&
+        (MappingInfo & 8) == 0 &&
+        isBuiltinExtensionDiag(DiagID))
+      Result = DiagnosticIDs::Error;
+
+    if (Diag.WarningsAsErrors)
+      Result = DiagnosticIDs::Error;
+    if (Result == DiagnosticIDs::Error && Diag.ErrorsAsFatal)
+      Result = DiagnosticIDs::Fatal;
+    break;
+
+  case diag::MAP_WARNING_NO_WERROR:
+    // Diagnostics specified with -Wno-error=foo should be set to warnings, but
+    // not be adjusted by -Werror or -pedantic-errors.
+    Result = DiagnosticIDs::Warning;
+
+    // If warnings are globally mapped to ignore or error, do it.
+    if (Diag.IgnoreAllWarnings)
+      return DiagnosticIDs::Ignored;
+
+    break;
+
+  case diag::MAP_ERROR_NO_WFATAL:
+    // Diagnostics specified as -Wno-fatal-error=foo should be errors, but
+    // unaffected by -Wfatal-errors.
+    Result = DiagnosticIDs::Error;
+    break;
+  }
+
+  // Okay, we're about to return this as a "diagnostic to emit" one last check:
+  // if this is any sort of extension warning, and if we're in an __extension__
+  // block, silence it.
+  if (Diag.AllExtensionsSilenced && isBuiltinExtensionDiag(DiagID))
+    return DiagnosticIDs::Ignored;
+
+  return Result;
+}
+
+struct WarningOption {
+  const char  *Name;
+  const short *Members;
+  const short *SubGroups;
+};
+
+#define GET_DIAG_ARRAYS
+#include "clang/Basic/DiagnosticGroups.inc"
+#undef GET_DIAG_ARRAYS
+
+// Second the table of options, sorted by name for fast binary lookup.
+static const WarningOption OptionTable[] = {
+#define GET_DIAG_TABLE
+#include "clang/Basic/DiagnosticGroups.inc"
+#undef GET_DIAG_TABLE
+};
+static const size_t OptionTableSize =
+sizeof(OptionTable) / sizeof(OptionTable[0]);
+
+static bool WarningOptionCompare(const WarningOption &LHS,
+                                 const WarningOption &RHS) {
+  return strcmp(LHS.Name, RHS.Name) < 0;
+}
+
+static void MapGroupMembers(const WarningOption *Group, diag::Mapping Mapping,
+                            Diagnostic &Diag) {
+  // Option exists, poke all the members of its diagnostic set.
+  if (const short *Member = Group->Members) {
+    for (; *Member != -1; ++Member)
+      Diag.setDiagnosticMapping(*Member, Mapping);
+  }
+
+  // Enable/disable all subgroups along with this one.
+  if (const short *SubGroups = Group->SubGroups) {
+    for (; *SubGroups != (short)-1; ++SubGroups)
+      MapGroupMembers(&OptionTable[(short)*SubGroups], Mapping, Diag);
+  }
+}
+
+/// setDiagnosticGroupMapping - Change an entire diagnostic group (e.g.
+/// "unknown-pragmas" to have the specified mapping.  This returns true and
+/// ignores the request if "Group" was unknown, false otherwise.
+bool DiagnosticIDs::setDiagnosticGroupMapping(const char *Group,
+                                           diag::Mapping Map,
+                                           Diagnostic &Diag) const {
+  WarningOption Key = { Group, 0, 0 };
+  const WarningOption *Found =
+  std::lower_bound(OptionTable, OptionTable + OptionTableSize, Key,
+                   WarningOptionCompare);
+  if (Found == OptionTable + OptionTableSize ||
+      strcmp(Found->Name, Group) != 0)
+    return true;  // Option not found.
+
+  MapGroupMembers(Found, Map, Diag);
+  return false;
+}
+
+/// ProcessDiag - This is the method used to report a diagnostic that is
+/// finally fully formed.
+bool DiagnosticIDs::ProcessDiag(Diagnostic &Diag) const {
+  DiagnosticInfo Info(&Diag);
+
+  if (Diag.SuppressAllDiagnostics)
+    return false;
+
+  assert(Diag.getClient() && "DiagnosticClient not set!");
+
+  // Figure out the diagnostic level of this message.
+  DiagnosticIDs::Level DiagLevel;
+  unsigned DiagID = Info.getID();
+
+  // ShouldEmitInSystemHeader - True if this diagnostic should be produced even
+  // in a system header.
+  bool ShouldEmitInSystemHeader;
+
+  if (DiagID >= diag::DIAG_UPPER_LIMIT) {
+    // Handle custom diagnostics, which cannot be mapped.
+    DiagLevel = CustomDiagInfo->getLevel(DiagID);
+
+    // Custom diagnostics always are emitted in system headers.
+    ShouldEmitInSystemHeader = true;
+  } else {
+    // Get the class of the diagnostic.  If this is a NOTE, map it onto whatever
+    // the diagnostic level was for the previous diagnostic so that it is
+    // filtered the same as the previous diagnostic.
+    unsigned DiagClass = getBuiltinDiagClass(DiagID);
+    if (DiagClass == CLASS_NOTE) {
+      DiagLevel = DiagnosticIDs::Note;
+      ShouldEmitInSystemHeader = false;  // extra consideration is needed
+    } else {
+      // If this is not an error and we are in a system header, we ignore it.
+      // Check the original Diag ID here, because we also want to ignore
+      // extensions and warnings in -Werror and -pedantic-errors modes, which
+      // *map* warnings/extensions to errors.
+      ShouldEmitInSystemHeader = DiagClass == CLASS_ERROR;
+
+      DiagLevel = getDiagnosticLevel(DiagID, DiagClass, Diag);
+    }
+  }
+
+  if (DiagLevel != DiagnosticIDs::Note) {
+    // Record that a fatal error occurred only when we see a second
+    // non-note diagnostic. This allows notes to be attached to the
+    // fatal error, but suppresses any diagnostics that follow those
+    // notes.
+    if (Diag.LastDiagLevel == DiagnosticIDs::Fatal)
+      Diag.FatalErrorOccurred = true;
+
+    Diag.LastDiagLevel = DiagLevel;
+  }
+
+  // If a fatal error has already been emitted, silence all subsequent
+  // diagnostics.
+  if (Diag.FatalErrorOccurred) {
+    if (DiagLevel >= DiagnosticIDs::Error &&
+        Diag.Client->IncludeInDiagnosticCounts()) {
+      ++Diag.NumErrors;
+      ++Diag.NumErrorsSuppressed;
+    }
+
+    return false;
+  }
+
+  // If the client doesn't care about this message, don't issue it.  If this is
+  // a note and the last real diagnostic was ignored, ignore it too.
+  if (DiagLevel == DiagnosticIDs::Ignored ||
+      (DiagLevel == DiagnosticIDs::Note &&
+       Diag.LastDiagLevel == DiagnosticIDs::Ignored))
+    return false;
+
+  // If this diagnostic is in a system header and is not a clang error, suppress
+  // it.
+  if (Diag.SuppressSystemWarnings && !ShouldEmitInSystemHeader &&
+      Info.getLocation().isValid() &&
+      Diag.getSourceManager().isInSystemHeader(
+          Diag.getSourceManager().getInstantiationLoc(Info.getLocation())) &&
+      (DiagLevel != DiagnosticIDs::Note ||
+       Diag.LastDiagLevel == DiagnosticIDs::Ignored)) {
+    Diag.LastDiagLevel = DiagnosticIDs::Ignored;
+    return false;
+  }
+
+  if (DiagLevel >= DiagnosticIDs::Error) {
+    if (Diag.Client->IncludeInDiagnosticCounts()) {
+      Diag.ErrorOccurred = true;
+      ++Diag.NumErrors;
+    }
+
+    // If we've emitted a lot of errors, emit a fatal error after it to stop a
+    // flood of bogus errors.
+    if (Diag.ErrorLimit && Diag.NumErrors >= Diag.ErrorLimit &&
+        DiagLevel == DiagnosticIDs::Error)
+      Diag.SetDelayedDiagnostic(diag::fatal_too_many_errors);
+  }
+
+  // Finally, report it.
+  Diag.Client->HandleDiagnostic((Diagnostic::Level)DiagLevel, Info);
+  if (Diag.Client->IncludeInDiagnosticCounts()) {
+    if (DiagLevel == DiagnosticIDs::Warning)
+      ++Diag.NumWarnings;
+  }
+
+  Diag.CurDiagID = ~0U;
+
+  return true;
+}

Modified: cfe/trunk/lib/Basic/SourceManager.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Basic/SourceManager.cpp?rev=119730&r1=119729&r2=119730&view=diff
==============================================================================
--- cfe/trunk/lib/Basic/SourceManager.cpp (original)
+++ cfe/trunk/lib/Basic/SourceManager.cpp Thu Nov 18 14:06:41 2010
@@ -100,7 +100,7 @@
         Diag.SetDelayedDiagnostic(diag::err_cannot_open_file, 
                                   Entry->getName(), ErrorStr);
       else 
-        Diag.Report(FullSourceLoc(Loc, SM), diag::err_cannot_open_file)
+        Diag.Report(Loc, diag::err_cannot_open_file)
           << Entry->getName() << ErrorStr;
 
       Buffer.setInt(Buffer.getInt() | InvalidFlag);
@@ -120,7 +120,7 @@
         Diag.SetDelayedDiagnostic(diag::err_file_modified,
                                   Entry->getName());
       else
-        Diag.Report(FullSourceLoc(Loc, SM), diag::err_file_modified)
+        Diag.Report(Loc, diag::err_file_modified)
           << Entry->getName();
 
       Buffer.setInt(Buffer.getInt() | InvalidFlag);
@@ -147,7 +147,7 @@
         .Default(0);
 
       if (BOM) {
-        Diag.Report(FullSourceLoc(Loc, SM), diag::err_unsupported_bom)
+        Diag.Report(Loc, diag::err_unsupported_bom)
           << BOM << Entry->getName();
         Buffer.setInt(1);
       }
@@ -342,6 +342,15 @@
 // Private 'Create' methods.
 //===----------------------------------------------------------------------===//
 
+SourceManager::SourceManager(Diagnostic &Diag, FileManager &FileMgr,
+                             const FileSystemOptions &FSOpts)
+  : Diag(Diag), FileMgr(FileMgr), FileSystemOpts(FSOpts),
+    ExternalSLocEntries(0), LineTable(0), NumLinearScans(0),
+    NumBinaryProbes(0) {
+  clearIDTables();
+  Diag.setSourceManager(this);
+}
+
 SourceManager::~SourceManager() {
   delete LineTable;
 

Modified: cfe/trunk/lib/Checker/PathDiagnostic.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Checker/PathDiagnostic.cpp?rev=119730&r1=119729&r2=119730&view=diff
==============================================================================
--- cfe/trunk/lib/Checker/PathDiagnostic.cpp (original)
+++ cfe/trunk/lib/Checker/PathDiagnostic.cpp Thu Nov 18 14:06:41 2010
@@ -104,7 +104,9 @@
   Info.FormatDiagnostic(StrC);
 
   PathDiagnosticPiece *P =
-    new PathDiagnosticEventPiece(Info.getLocation(), StrC.str());
+    new PathDiagnosticEventPiece(FullSourceLoc(Info.getLocation(),
+                                               Info.getSourceManager()),
+                                 StrC.str());
 
   for (unsigned i = 0, e = Info.getNumRanges(); i != e; ++i)
     P->addRange(Info.getRange(i).getAsRange());

Modified: cfe/trunk/lib/CodeGen/CGDebugInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGDebugInfo.cpp?rev=119730&r1=119729&r2=119730&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGDebugInfo.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGDebugInfo.cpp Thu Nov 18 14:06:41 2010
@@ -1529,7 +1529,7 @@
   assert(Diag && "Fall through without a diagnostic?");
   unsigned DiagID = CGM.getDiags().getCustomDiagID(Diagnostic::Error,
                                "debug information for %0 is not yet supported");
-  CGM.getDiags().Report(FullSourceLoc(), DiagID)
+  CGM.getDiags().Report(DiagID)
     << Diag;
   return llvm::DIType();
 }

Modified: cfe/trunk/lib/CodeGen/CodeGenAction.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenAction.cpp?rev=119730&r1=119729&r2=119730&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenAction.cpp (original)
+++ cfe/trunk/lib/CodeGen/CodeGenAction.cpp Thu Nov 18 14:06:41 2010
@@ -209,8 +209,7 @@
   // issue as being an error in the source with a note showing the instantiated
   // code.
   if (LocCookie.isValid()) {
-    Diags.Report(FullSourceLoc(LocCookie, Context->getSourceManager()),
-                 diag::err_fe_inline_asm).AddString(Message);
+    Diags.Report(LocCookie, diag::err_fe_inline_asm).AddString(Message);
     
     if (D.getLoc().isValid())
       Diags.Report(Loc, diag::note_fe_inline_asm_here);
@@ -318,7 +317,7 @@
       unsigned DiagID = CI.getDiagnostics().getCustomDiagID(Diagnostic::Error,
                                                             Msg);
 
-      CI.getDiagnostics().Report(FullSourceLoc(Loc, SM), DiagID);
+      CI.getDiagnostics().Report(Loc, DiagID);
       return;
     }
 

Modified: cfe/trunk/lib/CodeGen/Mangle.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/Mangle.cpp?rev=119730&r1=119729&r2=119730&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/Mangle.cpp (original)
+++ cfe/trunk/lib/CodeGen/Mangle.cpp Thu Nov 18 14:06:41 2010
@@ -525,7 +525,7 @@
     Diagnostic &Diags = Context.getDiags();
     unsigned DiagID = Diags.getCustomDiagID(Diagnostic::Error,
                                       "cannot mangle dependent operator name");
-    Diags.Report(FullSourceLoc(), DiagID);
+    Diags.Report(DiagID);
     return;
   }
   
@@ -1672,9 +1672,7 @@
     Diagnostic &Diags = Context.getDiags();
     unsigned DiagID = Diags.getCustomDiagID(Diagnostic::Error,
                                      "cannot yet mangle expression type %0");
-    Diags.Report(FullSourceLoc(E->getExprLoc(),
-                               getASTContext().getSourceManager()),
-                 DiagID)
+    Diags.Report(E->getExprLoc(), DiagID)
       << E->getStmtClassName() << E->getSourceRange();
     break;
   }

Modified: cfe/trunk/lib/Driver/Driver.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/Driver.cpp?rev=119730&r1=119729&r2=119730&view=diff
==============================================================================
--- cfe/trunk/lib/Driver/Driver.cpp (original)
+++ cfe/trunk/lib/Driver/Driver.cpp Thu Nov 18 14:06:41 2010
@@ -404,7 +404,7 @@
 /// option.
 static void PrintDiagnosticCategories(llvm::raw_ostream &OS) {
   for (unsigned i = 1; // Skip the empty category.
-       const char *CategoryName = Diagnostic::getCategoryNameFromID(i); ++i)
+       const char *CategoryName = DiagnosticIDs::getCategoryNameFromID(i); ++i)
     OS << i << ',' << CategoryName << '\n';
 }
 

Modified: cfe/trunk/lib/Frontend/ASTMerge.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/ASTMerge.cpp?rev=119730&r1=119729&r2=119730&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/ASTMerge.cpp (original)
+++ cfe/trunk/lib/Frontend/ASTMerge.cpp Thu Nov 18 14:06:41 2010
@@ -38,21 +38,18 @@
                                          CI.getASTContext().getLangOptions());
   CI.getDiagnostics().SetArgToStringFn(&FormatASTNodeDiagnosticArgument,
                                        &CI.getASTContext());
-  llvm::IntrusiveRefCntPtr<Diagnostic> Diags(&CI.getDiagnostics());
+  llvm::IntrusiveRefCntPtr<DiagnosticIDs>
+      DiagIDs(CI.getDiagnostics().getDiagnosticIDs());
   for (unsigned I = 0, N = ASTFiles.size(); I != N; ++I) {
+    llvm::IntrusiveRefCntPtr<Diagnostic>
+        Diags(new Diagnostic(DiagIDs, CI.getDiagnostics().getClient(),
+                             /*ShouldOwnClient=*/false));
     ASTUnit *Unit = ASTUnit::LoadFromASTFile(ASTFiles[I], Diags,
                                              CI.getFileSystemOpts(), false);
     if (!Unit)
       continue;
 
-    // Reset the argument -> string function so that it has the AST
-    // context we want, since the Sema object created by
-    // LoadFromASTFile will override it.
-    CI.getDiagnostics().SetArgToStringFn(&FormatASTNodeDiagnosticArgument,
-                                         &CI.getASTContext());
-
-    ASTImporter Importer(CI.getDiagnostics(),
-                         CI.getASTContext(), 
+    ASTImporter Importer(CI.getASTContext(), 
                          CI.getFileManager(),
                          CI.getFileSystemOpts(),
                          Unit->getASTContext(), 
@@ -72,6 +69,15 @@
       Importer.Import(*D);
     }
 
+    // Aggregate the number of warnings/errors from all diagnostics so
+    // that at CompilerInstance::ExecuteAction we can report the total numbers.
+    // FIXME: This is hacky, maybe keep track of total number of warnings/errors
+    // in DiagnosticClient and have CompilerInstance query that ?
+    CI.getDiagnostics().setNumWarnings(CI.getDiagnostics().getNumWarnings() +
+                                       Diags->getNumWarnings());
+    CI.getDiagnostics().setNumErrors(CI.getDiagnostics().getNumErrors() +
+                                     Diags->getNumErrors());
+
     delete Unit;
   }
 

Modified: cfe/trunk/lib/Frontend/CompilerInstance.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/CompilerInstance.cpp?rev=119730&r1=119729&r2=119730&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/CompilerInstance.cpp (original)
+++ cfe/trunk/lib/Frontend/CompilerInstance.cpp Thu Nov 18 14:06:41 2010
@@ -122,7 +122,8 @@
 CompilerInstance::createDiagnostics(const DiagnosticOptions &Opts,
                                     int Argc, const char* const *Argv,
                                     DiagnosticClient *Client) {
-  llvm::IntrusiveRefCntPtr<Diagnostic> Diags(new Diagnostic());
+  llvm::IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs());
+  llvm::IntrusiveRefCntPtr<Diagnostic> Diags(new Diagnostic(DiagID));
 
   // Create the diagnostic client for reporting errors or for
   // implementing -verify.

Modified: cfe/trunk/lib/Frontend/TextDiagnosticPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/TextDiagnosticPrinter.cpp?rev=119730&r1=119729&r2=119730&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/TextDiagnosticPrinter.cpp (original)
+++ cfe/trunk/lib/Frontend/TextDiagnosticPrinter.cpp Thu Nov 18 14:06:41 2010
@@ -776,7 +776,7 @@
   // If the location is specified, print out a file/line/col and include trace
   // if enabled.
   if (Info.getLocation().isValid()) {
-    const SourceManager &SM = Info.getLocation().getManager();
+    const SourceManager &SM = Info.getSourceManager();
     PresumedLoc PLoc = SM.getPresumedLoc(Info.getLocation());
     if (PLoc.isInvalid())
       return;
@@ -884,7 +884,8 @@
 
   std::string OptionName;
   if (DiagOpts->ShowOptionNames) {
-    if (const char *Opt = Diagnostic::getWarningOptionForDiag(Info.getID())) {
+    if (const char *
+          Opt = DiagnosticIDs::getWarningOptionForDiag(Info.getID())) {
       OptionName = "-W";
       OptionName += Opt;
     } else if (Info.getID() == diag::fatal_too_many_errors) {
@@ -893,7 +894,8 @@
       // If the diagnostic is an extension diagnostic and not enabled by default
       // then it must have been turned on with -pedantic.
       bool EnabledByDefault;
-      if (Diagnostic::isBuiltinExtensionDiag(Info.getID(), EnabledByDefault) &&
+      if (DiagnosticIDs::isBuiltinExtensionDiag(Info.getID(),
+                                                EnabledByDefault) &&
           !EnabledByDefault)
         OptionName = "-pedantic";
     }
@@ -902,7 +904,7 @@
   // If the user wants to see category information, include it too.
   unsigned DiagCategory = 0;
   if (DiagOpts->ShowCategories)
-    DiagCategory = Diagnostic::getCategoryNumberForDiag(Info.getID());
+    DiagCategory = DiagnosticIDs::getCategoryNumberForDiag(Info.getID());
 
   // If there is any categorization information, include it.
   if (!OptionName.empty() || DiagCategory != 0) {
@@ -920,7 +922,7 @@
         OutStr += llvm::utostr(DiagCategory);
       else {
         assert(DiagOpts->ShowCategories == 2 && "Invalid ShowCategories value");
-        OutStr += Diagnostic::getCategoryNameFromID(DiagCategory);
+        OutStr += DiagnosticIDs::getCategoryNameFromID(DiagCategory);
       }
     }
     
@@ -962,7 +964,7 @@
        (LastCaretDiagnosticWasNote && Level != Diagnostic::Note) ||
        Info.getNumFixItHints())) {
     // Cache the LastLoc, it allows us to omit duplicate source/caret spewage.
-    LastLoc = Info.getLocation();
+    LastLoc = FullSourceLoc(Info.getLocation(), Info.getSourceManager());
     LastCaretDiagnosticWasNote = (Level == Diagnostic::Note);
 
     // Get the ranges into a local array we can hack on.

Modified: cfe/trunk/lib/Parse/Parser.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/Parser.cpp?rev=119730&r1=119729&r2=119730&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/Parser.cpp (original)
+++ cfe/trunk/lib/Parse/Parser.cpp Thu Nov 18 14:06:41 2010
@@ -78,7 +78,7 @@
 
 
 DiagnosticBuilder Parser::Diag(SourceLocation Loc, unsigned DiagID) {
-  return Diags.Report(FullSourceLoc(Loc, PP.getSourceManager()), DiagID);
+  return Diags.Report(Loc, DiagID);
 }
 
 DiagnosticBuilder Parser::Diag(const Token &Tok, unsigned DiagID) {

Modified: cfe/trunk/lib/Rewrite/FixItRewriter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Rewrite/FixItRewriter.cpp?rev=119730&r1=119729&r2=119730&view=diff
==============================================================================
--- cfe/trunk/lib/Rewrite/FixItRewriter.cpp (original)
+++ cfe/trunk/lib/Rewrite/FixItRewriter.cpp Thu Nov 18 14:06:41 2010
@@ -141,7 +141,7 @@
 }
 
 /// \brief Emit a diagnostic via the adapted diagnostic client.
-void FixItRewriter::Diag(FullSourceLoc Loc, unsigned DiagID) {
+void FixItRewriter::Diag(SourceLocation Loc, unsigned DiagID) {
   // When producing this diagnostic, we temporarily bypass ourselves,
   // clear out any current diagnostic, and let the downstream client
   // format the diagnostic.

Modified: cfe/trunk/lib/Rewrite/HTMLRewrite.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Rewrite/HTMLRewrite.cpp?rev=119730&r1=119729&r2=119730&view=diff
==============================================================================
--- cfe/trunk/lib/Rewrite/HTMLRewrite.cpp (original)
+++ cfe/trunk/lib/Rewrite/HTMLRewrite.cpp Thu Nov 18 14:06:41 2010
@@ -486,7 +486,8 @@
 
   // Temporarily change the diagnostics object so that we ignore any generated
   // diagnostics from this pass.
-  Diagnostic TmpDiags(new IgnoringDiagClient);
+  Diagnostic TmpDiags(PP.getDiagnostics().getDiagnosticIDs(),
+                      new IgnoringDiagClient);
 
   // FIXME: This is a huge hack; we reuse the input preprocessor because we want
   // its state, but we aren't actually changing it (we hope). This should really

Modified: cfe/trunk/lib/Sema/DeclSpec.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/DeclSpec.cpp?rev=119730&r1=119729&r2=119730&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/DeclSpec.cpp (original)
+++ cfe/trunk/lib/Sema/DeclSpec.cpp Thu Nov 18 14:06:41 2010
@@ -23,8 +23,8 @@
 
 
 static DiagnosticBuilder Diag(Diagnostic &D, SourceLocation Loc,
-                              SourceManager &SrcMgr, unsigned DiagID) {
-  return D.Report(FullSourceLoc(Loc, SrcMgr), DiagID);
+                              unsigned DiagID) {
+  return D.Report(Loc, DiagID);
 }
 
 
@@ -512,28 +512,27 @@
   SaveStorageSpecifierAsWritten();
 
   // Check the type specifier components first.
-  SourceManager &SrcMgr = PP.getSourceManager();
 
   // Validate and finalize AltiVec vector declspec.
   if (TypeAltiVecVector) {
     if (TypeAltiVecBool) {
       // Sign specifiers are not allowed with vector bool. (PIM 2.1)
       if (TypeSpecSign != TSS_unspecified) {
-        Diag(D, TSSLoc, SrcMgr, diag::err_invalid_vector_bool_decl_spec)
+        Diag(D, TSSLoc, diag::err_invalid_vector_bool_decl_spec)
           << getSpecifierName((TSS)TypeSpecSign);
       }
 
       // Only char/int are valid with vector bool. (PIM 2.1)
       if (((TypeSpecType != TST_unspecified) && (TypeSpecType != TST_char) &&
            (TypeSpecType != TST_int)) || TypeAltiVecPixel) {
-        Diag(D, TSTLoc, SrcMgr, diag::err_invalid_vector_bool_decl_spec)
+        Diag(D, TSTLoc, diag::err_invalid_vector_bool_decl_spec)
           << (TypeAltiVecPixel ? "__pixel" :
                                  getSpecifierName((TST)TypeSpecType));
       }
 
       // Only 'short' is valid with vector bool. (PIM 2.1)
       if ((TypeSpecWidth != TSW_unspecified) && (TypeSpecWidth != TSW_short))
-        Diag(D, TSWLoc, SrcMgr, diag::err_invalid_vector_bool_decl_spec)
+        Diag(D, TSWLoc, diag::err_invalid_vector_bool_decl_spec)
           << getSpecifierName((TSW)TypeSpecWidth);
 
       // Elements of vector bool are interpreted as unsigned. (PIM 2.1)
@@ -557,7 +556,7 @@
       TypeSpecType = TST_int; // unsigned -> unsigned int, signed -> signed int.
     else if (TypeSpecType != TST_int  &&
              TypeSpecType != TST_char && TypeSpecType != TST_wchar) {
-      Diag(D, TSSLoc, SrcMgr, diag::err_invalid_sign_spec)
+      Diag(D, TSSLoc, diag::err_invalid_sign_spec)
         << getSpecifierName((TST)TypeSpecType);
       // signed double -> double.
       TypeSpecSign = TSS_unspecified;
@@ -572,7 +571,7 @@
     if (TypeSpecType == TST_unspecified)
       TypeSpecType = TST_int; // short -> short int, long long -> long long int.
     else if (TypeSpecType != TST_int) {
-      Diag(D, TSWLoc, SrcMgr,
+      Diag(D, TSWLoc,
            TypeSpecWidth == TSW_short ? diag::err_invalid_short_spec
                                       : diag::err_invalid_longlong_spec)
         <<  getSpecifierName((TST)TypeSpecType);
@@ -584,7 +583,7 @@
     if (TypeSpecType == TST_unspecified)
       TypeSpecType = TST_int;  // long -> long int.
     else if (TypeSpecType != TST_int && TypeSpecType != TST_double) {
-      Diag(D, TSWLoc, SrcMgr, diag::err_invalid_long_spec)
+      Diag(D, TSWLoc, diag::err_invalid_long_spec)
         << getSpecifierName((TST)TypeSpecType);
       TypeSpecType = TST_int;
       TypeSpecOwned = false;
@@ -596,16 +595,16 @@
   // disallow their use.  Need information about the backend.
   if (TypeSpecComplex != TSC_unspecified) {
     if (TypeSpecType == TST_unspecified) {
-      Diag(D, TSCLoc, SrcMgr, diag::ext_plain_complex)
+      Diag(D, TSCLoc, diag::ext_plain_complex)
         << FixItHint::CreateInsertion(
                               PP.getLocForEndOfToken(getTypeSpecComplexLoc()),
                                                  " double");
       TypeSpecType = TST_double;   // _Complex -> _Complex double.
     } else if (TypeSpecType == TST_int || TypeSpecType == TST_char) {
       // Note that this intentionally doesn't include _Complex _Bool.
-      Diag(D, TSTLoc, SrcMgr, diag::ext_integer_complex);
+      Diag(D, TSTLoc, diag::ext_integer_complex);
     } else if (TypeSpecType != TST_float && TypeSpecType != TST_double) {
-      Diag(D, TSCLoc, SrcMgr, diag::err_invalid_complex_spec)
+      Diag(D, TSCLoc, diag::err_invalid_complex_spec)
         << getSpecifierName((TST)TypeSpecType);
       TypeSpecComplex = TSC_unspecified;
     }
@@ -621,7 +620,7 @@
     SourceLocation SCLoc = getStorageClassSpecLoc();
     SourceLocation SCEndLoc = SCLoc.getFileLocWithOffset(strlen(SpecName));
 
-    Diag(D, SCLoc, SrcMgr, diag::err_friend_storage_spec)
+    Diag(D, SCLoc, diag::err_friend_storage_spec)
       << SpecName
       << FixItHint::CreateRemoval(SourceRange(SCLoc, SCEndLoc));
 

Modified: cfe/trunk/lib/Sema/Sema.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.cpp?rev=119730&r1=119729&r2=119730&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/Sema.cpp (original)
+++ cfe/trunk/lib/Sema/Sema.cpp Thu Nov 18 14:06:41 2010
@@ -438,12 +438,12 @@
     return;
   
   if (TemplateDeductionInfo *Info = SemaRef.isSFINAEContext()) {
-    switch (Diagnostic::getDiagnosticSFINAEResponse(getDiagID())) {
-    case Diagnostic::SFINAE_Report:
+    switch (DiagnosticIDs::getDiagnosticSFINAEResponse(getDiagID())) {
+    case DiagnosticIDs::SFINAE_Report:
       // Fall through; we'll report the diagnostic below.
       break;
       
-    case Diagnostic::SFINAE_SubstitutionFailure:
+    case DiagnosticIDs::SFINAE_SubstitutionFailure:
       // Count this failure so that we know that template argument deduction
       // has failed.
       ++SemaRef.NumSFINAEErrors;
@@ -452,7 +452,7 @@
       Clear();
       return;
       
-    case Diagnostic::SFINAE_Suppress:
+    case DiagnosticIDs::SFINAE_Suppress:
       // Make a copy of this suppressed diagnostic and store it with the
       // template-deduction information;
       FlushCounts();
@@ -478,7 +478,7 @@
   // that is different from the last template instantiation where
   // we emitted an error, print a template instantiation
   // backtrace.
-  if (!SemaRef.Diags.isBuiltinNote(DiagID) &&
+  if (!DiagnosticIDs::isBuiltinNote(DiagID) &&
       !SemaRef.ActiveTemplateInstantiations.empty() &&
       SemaRef.ActiveTemplateInstantiations.back()
         != SemaRef.LastTemplateInstantiationErrorContext) {
@@ -489,7 +489,7 @@
 }
 
 Sema::SemaDiagnosticBuilder Sema::Diag(SourceLocation Loc, unsigned DiagID) {
-  DiagnosticBuilder DB = Diags.Report(FullSourceLoc(Loc, SourceMgr), DiagID);
+  DiagnosticBuilder DB = Diags.Report(Loc, DiagID);
   return SemaDiagnosticBuilder(DB, *this, DiagID);
 }
 

Modified: cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp?rev=119730&r1=119729&r2=119730&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp Thu Nov 18 14:06:41 2010
@@ -382,7 +382,7 @@
     if (InstantiationIdx >= SkipStart && InstantiationIdx < SkipEnd) {
       if (InstantiationIdx == SkipStart) {
         // Note that we're skipping instantiations.
-        Diags.Report(FullSourceLoc(Active->PointOfInstantiation, SourceMgr),
+        Diags.Report(Active->PointOfInstantiation,
                      diag::note_instantiation_contexts_suppressed)
           << unsigned(ActiveTemplateInstantiations.size() - Limit);
       }
@@ -396,8 +396,7 @@
         unsigned DiagID = diag::note_template_member_class_here;
         if (isa<ClassTemplateSpecializationDecl>(Record))
           DiagID = diag::note_template_class_instantiation_here;
-        Diags.Report(FullSourceLoc(Active->PointOfInstantiation, SourceMgr),
-                     DiagID)
+        Diags.Report(Active->PointOfInstantiation, DiagID)
           << Context.getTypeDeclType(Record)
           << Active->InstantiationRange;
       } else if (FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
@@ -406,12 +405,11 @@
           DiagID = diag::note_function_template_spec_here;
         else
           DiagID = diag::note_template_member_function_here;
-        Diags.Report(FullSourceLoc(Active->PointOfInstantiation, SourceMgr),
-                     DiagID)
+        Diags.Report(Active->PointOfInstantiation, DiagID)
           << Function
           << Active->InstantiationRange;
       } else {
-        Diags.Report(FullSourceLoc(Active->PointOfInstantiation, SourceMgr),
+        Diags.Report(Active->PointOfInstantiation,
                      diag::note_template_static_data_member_def_here)
           << cast<VarDecl>(D)
           << Active->InstantiationRange;
@@ -426,7 +424,7 @@
                                                          Active->TemplateArgs,
                                                       Active->NumTemplateArgs,
                                                       Context.PrintingPolicy);
-      Diags.Report(FullSourceLoc(Active->PointOfInstantiation, SourceMgr),
+      Diags.Report(Active->PointOfInstantiation,
                    diag::note_default_arg_instantiation_here)
         << (Template->getNameAsString() + TemplateArgsStr)
         << Active->InstantiationRange;
@@ -436,7 +434,7 @@
     case ActiveTemplateInstantiation::ExplicitTemplateArgumentSubstitution: {
       FunctionTemplateDecl *FnTmpl
         = cast<FunctionTemplateDecl>((Decl *)Active->Entity);
-      Diags.Report(FullSourceLoc(Active->PointOfInstantiation, SourceMgr),
+      Diags.Report(Active->PointOfInstantiation,
                    diag::note_explicit_template_arg_substitution_here)
         << FnTmpl 
         << getTemplateArgumentBindingsText(FnTmpl->getTemplateParameters(), 
@@ -450,7 +448,7 @@
       if (ClassTemplatePartialSpecializationDecl *PartialSpec
             = dyn_cast<ClassTemplatePartialSpecializationDecl>(
                                                     (Decl *)Active->Entity)) {
-        Diags.Report(FullSourceLoc(Active->PointOfInstantiation, SourceMgr),
+        Diags.Report(Active->PointOfInstantiation,
                      diag::note_partial_spec_deduct_instantiation_here)
           << Context.getTypeDeclType(PartialSpec)
           << getTemplateArgumentBindingsText(
@@ -461,7 +459,7 @@
       } else {
         FunctionTemplateDecl *FnTmpl
           = cast<FunctionTemplateDecl>((Decl *)Active->Entity);
-        Diags.Report(FullSourceLoc(Active->PointOfInstantiation, SourceMgr),
+        Diags.Report(Active->PointOfInstantiation,
                      diag::note_function_template_deduction_instantiation_here)
           << FnTmpl
           << getTemplateArgumentBindingsText(FnTmpl->getTemplateParameters(), 
@@ -480,7 +478,7 @@
                                                          Active->TemplateArgs,
                                                       Active->NumTemplateArgs,
                                                       Context.PrintingPolicy);
-      Diags.Report(FullSourceLoc(Active->PointOfInstantiation, SourceMgr),
+      Diags.Report(Active->PointOfInstantiation,
                    diag::note_default_function_arg_instantiation_here)
         << (FD->getNameAsString() + TemplateArgsStr)
         << Active->InstantiationRange;
@@ -493,7 +491,7 @@
       if (!Parm->getName().empty())
         Name = std::string(" '") + Parm->getName().str() + "'";
                                         
-      Diags.Report(FullSourceLoc(Active->PointOfInstantiation, SourceMgr),
+      Diags.Report(Active->PointOfInstantiation,
                    diag::note_prior_template_arg_substitution)
         << isa<TemplateTemplateParmDecl>(Parm)
         << Name
@@ -506,7 +504,7 @@
     }
 
     case ActiveTemplateInstantiation::DefaultTemplateArgumentChecking: {
-      Diags.Report(FullSourceLoc(Active->PointOfInstantiation, SourceMgr),
+      Diags.Report(Active->PointOfInstantiation,
                    diag::note_template_default_arg_checking)
         << getTemplateArgumentBindingsText(
                                      Active->Template->getTemplateParameters(), 

Modified: cfe/trunk/lib/Serialization/ASTReader.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReader.cpp?rev=119730&r1=119729&r2=119730&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTReader.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTReader.cpp Thu Nov 18 14:06:41 2010
@@ -4383,7 +4383,7 @@
 }
 
 DiagnosticBuilder ASTReader::Diag(SourceLocation Loc, unsigned DiagID) {
-  return Diags.Report(FullSourceLoc(Loc, SourceMgr), DiagID);
+  return Diags.Report(Loc, DiagID);
 }
 
 /// \brief Retrieve the identifier table associated with the

Modified: cfe/trunk/tools/driver/cc1_main.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/driver/cc1_main.cpp?rev=119730&r1=119729&r2=119730&view=diff
==============================================================================
--- cfe/trunk/tools/driver/cc1_main.cpp (original)
+++ cfe/trunk/tools/driver/cc1_main.cpp Thu Nov 18 14:06:41 2010
@@ -116,13 +116,14 @@
 int cc1_main(const char **ArgBegin, const char **ArgEnd,
              const char *Argv0, void *MainAddr) {
   llvm::OwningPtr<CompilerInstance> Clang(new CompilerInstance());
+  llvm::IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs());
 
   Clang->setLLVMContext(new llvm::LLVMContext());
 
   // Run clang -cc1 test.
   if (ArgBegin != ArgEnd && llvm::StringRef(ArgBegin[0]) == "-cc1test") {
-    Diagnostic Diags(new TextDiagnosticPrinter(llvm::errs(), 
-                                               DiagnosticOptions()));
+    Diagnostic Diags(DiagID, new TextDiagnosticPrinter(llvm::errs(), 
+                                                       DiagnosticOptions()));
     return cc1_test(Diags, ArgBegin + 1, ArgEnd);
   }
 
@@ -134,7 +135,7 @@
   // Buffer diagnostics from argument parsing so that we can output them using a
   // well formed diagnostic object.
   TextDiagnosticBuffer *DiagsBuffer = new TextDiagnosticBuffer;
-  Diagnostic Diags(DiagsBuffer);
+  Diagnostic Diags(DiagID, DiagsBuffer);
   CompilerInvocation::CreateFromArgs(Clang->getInvocation(), ArgBegin, ArgEnd,
                                      Diags);
 

Modified: cfe/trunk/tools/driver/cc1as_main.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/driver/cc1as_main.cpp?rev=119730&r1=119729&r2=119730&view=diff
==============================================================================
--- cfe/trunk/tools/driver/cc1as_main.cpp (original)
+++ cfe/trunk/tools/driver/cc1as_main.cpp Thu Nov 18 14:06:41 2010
@@ -326,7 +326,8 @@
   TextDiagnosticPrinter *DiagClient
     = new TextDiagnosticPrinter(errs(), DiagnosticOptions());
   DiagClient->setPrefix("clang -cc1as");
-  Diagnostic Diags(DiagClient);
+  llvm::IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs());
+  Diagnostic Diags(DiagID, DiagClient);
 
   // Set an error handler, so that any LLVM backend diagnostics go through our
   // error handler.

Modified: cfe/trunk/tools/driver/driver.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/driver/driver.cpp?rev=119730&r1=119729&r2=119730&view=diff
==============================================================================
--- cfe/trunk/tools/driver/driver.cpp (original)
+++ cfe/trunk/tools/driver/driver.cpp Thu Nov 18 14:06:41 2010
@@ -288,7 +288,8 @@
   TextDiagnosticPrinter *DiagClient
     = new TextDiagnosticPrinter(llvm::errs(), DiagnosticOptions());
   DiagClient->setPrefix(Path.getBasename());
-  Diagnostic Diags(DiagClient);
+  llvm::IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs());
+  Diagnostic Diags(DiagID, DiagClient);
 
 #ifdef CLANG_IS_PRODUCTION
   const bool IsProduction = true;

Modified: cfe/trunk/tools/libclang/CIndexCodeCompletion.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/CIndexCodeCompletion.cpp?rev=119730&r1=119729&r2=119730&view=diff
==============================================================================
--- cfe/trunk/tools/libclang/CIndexCodeCompletion.cpp (original)
+++ cfe/trunk/tools/libclang/CIndexCodeCompletion.cpp Thu Nov 18 14:06:41 2010
@@ -258,7 +258,9 @@
 static unsigned CodeCompletionResultObjects;
   
 AllocatedCXCodeCompleteResults::AllocatedCXCodeCompleteResults() 
-  : CXCodeCompleteResults(), Diag(new Diagnostic),
+  : CXCodeCompleteResults(),
+    Diag(new Diagnostic(
+                   llvm::IntrusiveRefCntPtr<DiagnosticIDs>(new DiagnosticIDs))),
     SourceMgr(*Diag, FileMgr, FileSystemOpts) { 
   if (getenv("LIBCLANG_OBJTRACKING")) {
     ++CodeCompletionResultObjects;





More information about the cfe-commits mailing list