[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