summaryrefslogtreecommitdiffstats
path: root/clang/include/clang
diff options
context:
space:
mode:
Diffstat (limited to 'clang/include/clang')
-rw-r--r--clang/include/clang/Analysis/PathDiagnostic.h18
-rw-r--r--clang/include/clang/Basic/Diagnostic.h107
-rw-r--r--clang/include/clang/Basic/DiagnosticParseKinds.def3
-rw-r--r--clang/include/clang/Basic/TokenKinds.h1
-rw-r--r--clang/include/clang/Driver/TextDiagnosticPrinter.h4
-rw-r--r--clang/include/clang/Parse/Action.h6
-rw-r--r--clang/include/clang/Parse/Parser.h29
7 files changed, 151 insertions, 17 deletions
diff --git a/clang/include/clang/Analysis/PathDiagnostic.h b/clang/include/clang/Analysis/PathDiagnostic.h
index bc68ac59116..cee11c27b59 100644
--- a/clang/include/clang/Analysis/PathDiagnostic.h
+++ b/clang/include/clang/Analysis/PathDiagnostic.h
@@ -31,6 +31,7 @@ public:
private:
FullSourceLoc Pos;
std::string str;
+ std::vector<CodeModificationHint> CodeModificationHints;
DisplayHint Hint;
std::vector<SourceRange> ranges;
@@ -56,6 +57,10 @@ public:
ranges.push_back(SourceRange(B,E));
}
+ void addCodeModificationHint(const CodeModificationHint& Hint) {
+ CodeModificationHints.push_back(Hint);
+ }
+
typedef const SourceRange* range_iterator;
range_iterator ranges_begin() const {
@@ -65,7 +70,18 @@ public:
range_iterator ranges_end() const {
return ranges_begin() + ranges.size();
}
-
+
+ typedef const CodeModificationHint *code_modifications_iterator;
+
+ code_modifications_iterator code_modifications_begin() const {
+ return CodeModificationHints.empty()? 0 : &CodeModificationHints[0];
+ }
+
+ code_modifications_iterator code_modifications_end() const {
+ return CodeModificationHints.empty()? 0
+ : &CodeModificationHints[0] + CodeModificationHints.size();
+ }
+
const SourceManager& getSourceManager() const {
return Pos.getManager();
}
diff --git a/clang/include/clang/Basic/Diagnostic.h b/clang/include/clang/Basic/Diagnostic.h
index db62ca95e75..7204abbd2af 100644
--- a/clang/include/clang/Basic/Diagnostic.h
+++ b/clang/include/clang/Basic/Diagnostic.h
@@ -68,6 +68,69 @@ namespace clang {
};
}
+/// \brief Annotates a diagnostic with some code that should be
+/// inserted, removed, or replaced to fix the problem.
+///
+/// This kind of hint should be used when we are certain that the
+/// introduction, removal, or modification of a particular (small!)
+/// amount of code will correct a compilation error. The compiler
+/// should also provide full recovery from such errors, such that
+/// suppressing the diagnostic output can still result successful
+/// compilation.
+class CodeModificationHint {
+public:
+ /// \brief Tokens that should be removed to correct the error.
+ SourceRange RemoveRange;
+
+ /// \brief The location at which we should insert code to correct
+ /// the error.
+ SourceLocation InsertionLoc;
+
+ /// \brief The actual code to insert at the insertion location, as a
+ /// string.
+ std::string CodeToInsert;
+
+ /// \brief Empty code modification hint, indicating that no code
+ /// modification is known.
+ CodeModificationHint() : RemoveRange(), InsertionLoc() { }
+
+ /// \brief Create a code modification hint that inserts the given
+ /// code string at a specific location.
+ CodeModificationHint(SourceLocation InsertionLoc, const std::string &Code)
+ : RemoveRange(), InsertionLoc(InsertionLoc), CodeToInsert(Code) { }
+
+ /// \brief Create a code modification hint that removes the given
+ /// source range.
+ CodeModificationHint(SourceRange RemoveRange)
+ : RemoveRange(RemoveRange), InsertionLoc(), CodeToInsert() { }
+
+ /// \brief Create a code modification hint that replaces the given
+ /// source range with the given code string.
+ CodeModificationHint(SourceRange RemoveRange, const std::string &Code)
+ : RemoveRange(RemoveRange), InsertionLoc(RemoveRange.getBegin()),
+ CodeToInsert(Code) { }
+};
+
+/// \brief Creates a code modification hint that inserts the given
+/// string at a particular location in the source code.
+inline CodeModificationHint
+CodeInsertionHint(SourceLocation InsertionLoc, const std::string &Code) {
+ return CodeModificationHint(InsertionLoc, Code);
+}
+
+/// \brief Creates a code modification hint that removes the given
+/// source range.
+inline CodeModificationHint CodeRemovalHint(SourceRange RemoveRange) {
+ return CodeModificationHint(RemoveRange);
+}
+
+/// \brief Creates a code modification hint that replaces the given
+/// source range with the given code string.
+inline CodeModificationHint
+CodeReplacementHint(SourceRange RemoveRange, const std::string &Code) {
+ return CodeModificationHint(RemoveRange, Code);
+}
+
/// 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
@@ -272,6 +335,9 @@ private:
signed char NumDiagArgs;
/// NumRanges - This is the number of ranges in the DiagRanges array.
unsigned char NumDiagRanges;
+ /// \brief The number of code modifications hints in the
+ /// CodeModificationHints array.
+ unsigned char NumCodeModificationHints;
/// DiagArgumentsKind - This is an array of ArgumentKind::ArgumentKind enum
/// values, with one for each argument. This specifies whether the argument
@@ -293,6 +359,12 @@ private:
/// only support 10 ranges, could easily be extended if needed.
const SourceRange *DiagRanges[10];
+ enum { MaxCodeModificationHints = 3 };
+
+ /// CodeModificationHints - If valid, provides a hint with some code
+ /// to insert, remove, or modify at a particular position.
+ CodeModificationHint CodeModificationHints[MaxCodeModificationHints];
+
/// ProcessDiag - This is the method used to report a diagnostic that is
/// finally fully formed.
void ProcessDiag();
@@ -315,12 +387,13 @@ private:
/// for example.
class DiagnosticBuilder {
mutable Diagnostic *DiagObj;
- mutable unsigned NumArgs, NumRanges;
+ mutable unsigned NumArgs, NumRanges, NumCodeModificationHints;
void operator=(const DiagnosticBuilder&); // DO NOT IMPLEMENT
friend class Diagnostic;
explicit DiagnosticBuilder(Diagnostic *diagObj)
- : DiagObj(diagObj), NumArgs(0), NumRanges(0) {}
+ : DiagObj(diagObj), NumArgs(0), NumRanges(0),
+ NumCodeModificationHints(0) {}
public:
/// Copy constructor. When copied, this "takes" the diagnostic info from the
@@ -339,6 +412,7 @@ public:
// the Diagnostic object.
DiagObj->NumDiagArgs = NumArgs;
DiagObj->NumDiagRanges = NumRanges;
+ DiagObj->NumCodeModificationHints = NumCodeModificationHints;
// Process the diagnostic, sending the accumulated information to the
// DiagnosticClient.
@@ -373,6 +447,12 @@ public:
"Too many arguments to diagnostic!");
DiagObj->DiagRanges[NumRanges++] = &R;
}
+
+ void AddCodeModificationHint(const CodeModificationHint &Hint) const {
+ assert(NumCodeModificationHints < Diagnostic::MaxCodeModificationHints &&
+ "Too many code modification hints!");
+ DiagObj->CodeModificationHints[NumCodeModificationHints++] = Hint;
+ }
};
inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
@@ -416,6 +496,12 @@ inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
DB.AddSourceRange(R);
return DB;
}
+
+inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
+ const CodeModificationHint &Hint) {
+ DB.AddCodeModificationHint(Hint);
+ return DB;
+}
/// Report - Issue the message to the client. DiagID is a member of the
@@ -433,7 +519,7 @@ inline DiagnosticBuilder Diagnostic::Report(FullSourceLoc Loc, unsigned DiagID){
//===----------------------------------------------------------------------===//
/// DiagnosticInfo - This is a little helper class (which is basically a smart
-/// pointer that forward info from Diagnostic) that allows clients ot enquire
+/// pointer that forward info from Diagnostic) that allows clients to enquire
/// about the currently in-flight diagnostic.
class DiagnosticInfo {
const Diagnostic *DiagObj;
@@ -507,14 +593,25 @@ public:
return *DiagObj->DiagRanges[Idx];
}
-
+ unsigned getNumCodeModificationHints() const {
+ return DiagObj->NumCodeModificationHints;
+ }
+
+ const CodeModificationHint &getCodeModificationHint(unsigned Idx) const {
+ return DiagObj->CodeModificationHints[Idx];
+ }
+
+ const CodeModificationHint *getCodeModificationHints() const {
+ return DiagObj->NumCodeModificationHints?
+ &DiagObj->CodeModificationHints[0] : 0;
+ }
+
/// FormatDiagnostic - Format this diagnostic into a string, substituting the
/// formal arguments into the %0 slots. The result is appended onto the Str
/// array.
void FormatDiagnostic(llvm::SmallVectorImpl<char> &OutStr) const;
};
-
/// DiagnosticClient - This is an abstract interface implemented by clients of
/// the front-end, which formats and prints fully processed diagnostics.
class DiagnosticClient {
diff --git a/clang/include/clang/Basic/DiagnosticParseKinds.def b/clang/include/clang/Basic/DiagnosticParseKinds.def
index 03868cda497..703d6b875cd 100644
--- a/clang/include/clang/Basic/DiagnosticParseKinds.def
+++ b/clang/include/clang/Basic/DiagnosticParseKinds.def
@@ -280,6 +280,9 @@ DIAG(err_less_after_template_name_in_nested_name_spec, ERROR,
"expected '<' after 'template %0' in nested name specifier")
DIAG(err_two_right_angle_brackets_need_space, ERROR,
"a space is required between consecutive right angle brackets (use '> >')")
+DIAG(warn_cxx0x_right_shift_in_template_arg, WARNING,
+ "use of right-shift operator ('>>') in template argument will require "
+ "parentheses in C++0x")
// Language specific pragmas
diff --git a/clang/include/clang/Basic/TokenKinds.h b/clang/include/clang/Basic/TokenKinds.h
index cfef30b4f5e..6a14244362c 100644
--- a/clang/include/clang/Basic/TokenKinds.h
+++ b/clang/include/clang/Basic/TokenKinds.h
@@ -44,6 +44,7 @@ enum ObjCKeywordKind {
};
const char *getTokenName(enum TokenKind Kind);
+const char *getTokenSpelling(enum TokenKind Kind);
} // end namespace tok
} // end namespace clang
diff --git a/clang/include/clang/Driver/TextDiagnosticPrinter.h b/clang/include/clang/Driver/TextDiagnosticPrinter.h
index 8d702b4934e..4a332b28a8a 100644
--- a/clang/include/clang/Driver/TextDiagnosticPrinter.h
+++ b/clang/include/clang/Driver/TextDiagnosticPrinter.h
@@ -48,7 +48,9 @@ public:
void EmitCaretDiagnostic(SourceLocation Loc,
SourceRange *Ranges, unsigned NumRanges,
- SourceManager &SM);
+ SourceManager &SM,
+ const CodeModificationHint *Hints = 0,
+ unsigned NumHints = 0);
virtual void HandleDiagnostic(Diagnostic::Level DiagLevel,
const DiagnosticInfo &Info);
diff --git a/clang/include/clang/Parse/Action.h b/clang/include/clang/Parse/Action.h
index ebcd79caaee..a7f2e767b3f 100644
--- a/clang/include/clang/Parse/Action.h
+++ b/clang/include/clang/Parse/Action.h
@@ -551,6 +551,12 @@ public:
// Primary Expressions.
+ /// \brief Retrieve the source range that corresponds to the given
+ /// expression.
+ virtual SourceRange getExprRange(ExprTy *E) const {
+ return SourceRange();
+ }
+
/// ActOnIdentifierExpr - Parse an identifier in expression context.
/// 'HasTrailingLParen' indicates whether or not the identifier has a '('
/// token immediately after it.
diff --git a/clang/include/clang/Parse/Parser.h b/clang/include/clang/Parse/Parser.h
index 1e3ea317dab..5d5265df358 100644
--- a/clang/include/clang/Parse/Parser.h
+++ b/clang/include/clang/Parse/Parser.h
@@ -37,6 +37,12 @@ class Parser {
/// that this is valid.
Token Tok;
+ // PrevTokLocation - The location of the token we previously
+ // consumed. This token is used for diagnostics where we expected to
+ // see a token following another token (e.g., the ';' at the end of
+ // a statement).
+ SourceLocation PrevTokLocation;
+
unsigned short ParenCount, BracketCount, BraceCount;
/// Actions - These are the callbacks we invoke as we parse various constructs
@@ -175,9 +181,9 @@ private:
assert(!isTokenStringLiteral() && !isTokenParen() && !isTokenBracket() &&
!isTokenBrace() &&
"Should consume special tokens with Consume*Token");
- SourceLocation L = Tok.getLocation();
+ PrevTokLocation = Tok.getLocation();
PP.Lex(Tok);
- return L;
+ return PrevTokLocation;
}
/// ConsumeAnyToken - Dispatch to the right Consume* method based on the
@@ -204,9 +210,9 @@ private:
++ParenCount;
else if (ParenCount)
--ParenCount; // Don't let unbalanced )'s drive the count negative.
- SourceLocation L = Tok.getLocation();
+ PrevTokLocation = Tok.getLocation();
PP.Lex(Tok);
- return L;
+ return PrevTokLocation;
}
/// ConsumeBracket - This consume method keeps the bracket count up-to-date.
@@ -218,9 +224,9 @@ private:
else if (BracketCount)
--BracketCount; // Don't let unbalanced ]'s drive the count negative.
- SourceLocation L = Tok.getLocation();
+ PrevTokLocation = Tok.getLocation();
PP.Lex(Tok);
- return L;
+ return PrevTokLocation;
}
/// ConsumeBrace - This consume method keeps the brace count up-to-date.
@@ -232,9 +238,9 @@ private:
else if (BraceCount)
--BraceCount; // Don't let unbalanced }'s drive the count negative.
- SourceLocation L = Tok.getLocation();
+ PrevTokLocation = Tok.getLocation();
PP.Lex(Tok);
- return L;
+ return PrevTokLocation;
}
/// ConsumeStringToken - Consume the current 'peek token', lexing a new one
@@ -244,9 +250,9 @@ private:
SourceLocation ConsumeStringToken() {
assert(isTokenStringLiteral() &&
"Should only consume string literals with this method");
- SourceLocation L = Tok.getLocation();
+ PrevTokLocation = Tok.getLocation();
PP.Lex(Tok);
- return L;
+ return PrevTokLocation;
}
/// GetLookAheadToken - This peeks ahead N tokens and returns that token
@@ -399,6 +405,9 @@ private:
DiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID);
DiagnosticBuilder Diag(const Token &Tok, unsigned DiagID);
+ void SuggestParentheses(SourceLocation Loc, unsigned DK,
+ SourceRange ParenRange);
+
/// SkipUntil - Read tokens until we get to the specified token, then consume
/// it (unless DontConsume is true). Because we cannot guarantee that the
/// token will ever occur, this skips to the next token, or to some likely
OpenPOWER on IntegriCloud