summaryrefslogtreecommitdiffstats
path: root/include/clang
diff options
context:
space:
mode:
authorAlex Lorenz <arphaman@gmail.com>2017-04-19 08:58:56 +0000
committerAlex Lorenz <arphaman@gmail.com>2017-04-19 08:58:56 +0000
commitaac41bcdb19f21fb20a2efdc19494b622ba29171 (patch)
tree345ec850b0f432a0708b5559ca86da3e1c25cdbc /include/clang
parentad25f8b712f1ef99020fcb7b5e31dd95b39c6112 (diff)
Add support for editor placeholders to Clang
This commit teaches Clang to recognize editor placeholders that are produced when an IDE like Xcode inserts a code-completion result that includes a placeholder. Now when the lexer sees a placeholder token, it emits an 'editor placeholder in source file' error and creates an identifier token that represents the placeholder. The parser/sema can now recognize the placeholders and can suppress the diagnostics related to the placeholders. This ensures that live issues in an IDE like Xcode won't get spurious diagnostics related to placeholders. This commit also adds a new compiler option named '-fallow-editor-placeholders' that silences the 'editor placeholder in source file' error. This is useful for an IDE like Xcode as we don't want to display those errors in live issues. rdar://31581400 Differential Revision: https://reviews.llvm.org/D32081 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@300667 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'include/clang')
-rw-r--r--include/clang/Basic/DiagnosticLexKinds.td1
-rw-r--r--include/clang/Basic/IdentifierTable.h13
-rw-r--r--include/clang/Basic/LangOptions.def2
-rw-r--r--include/clang/Driver/Options.td6
-rw-r--r--include/clang/Lex/Lexer.h2
-rw-r--r--include/clang/Lex/Token.h8
6 files changed, 32 insertions, 0 deletions
diff --git a/include/clang/Basic/DiagnosticLexKinds.td b/include/clang/Basic/DiagnosticLexKinds.td
index b5b5acbc78..cf33d5fba3 100644
--- a/include/clang/Basic/DiagnosticLexKinds.td
+++ b/include/clang/Basic/DiagnosticLexKinds.td
@@ -242,6 +242,7 @@ def warn_bad_character_encoding : ExtWarn<
"illegal character encoding in character literal">,
InGroup<InvalidSourceEncoding>;
def err_lexing_string : Error<"failure when lexing a string">;
+def err_placeholder_in_source : Error<"editor placeholder in source file">;
//===----------------------------------------------------------------------===//
diff --git a/include/clang/Basic/IdentifierTable.h b/include/clang/Basic/IdentifierTable.h
index a5fd14104d..9b1ba4a98e 100644
--- a/include/clang/Basic/IdentifierTable.h
+++ b/include/clang/Basic/IdentifierTable.h
@@ -355,6 +355,19 @@ public:
RecomputeNeedsHandleIdentifier();
}
+ /// Return true if this identifier is an editor placeholder.
+ ///
+ /// Editor placeholders are produced by the code-completion engine and are
+ /// represented as characters between '<#' and '#>' in the source code. An
+ /// example of auto-completed call with a placeholder parameter is shown
+ /// below:
+ /// \code
+ /// function(<#int x#>);
+ /// \endcode
+ bool isEditorPlaceholder() const {
+ return getName().startswith("<#") && getName().endswith("#>");
+ }
+
/// \brief Provide less than operator for lexicographical sorting.
bool operator<(const IdentifierInfo &RHS) const {
return getName() < RHS.getName();
diff --git a/include/clang/Basic/LangOptions.def b/include/clang/Basic/LangOptions.def
index c8e1972997..6ae34a89fe 100644
--- a/include/clang/Basic/LangOptions.def
+++ b/include/clang/Basic/LangOptions.def
@@ -266,6 +266,8 @@ LANGOPT(SanitizeAddressFieldPadding, 2, 0, "controls how aggressive is ASan "
LANGOPT(XRayInstrument, 1, 0, "controls whether to do XRay instrumentation")
+LANGOPT(AllowEditorPlaceholders, 1, 0, "allow editor placeholders in source")
+
#undef LANGOPT
#undef COMPATIBLE_LANGOPT
#undef BENIGN_LANGOPT
diff --git a/include/clang/Driver/Options.td b/include/clang/Driver/Options.td
index c6c9d5d889..6f1ccfb001 100644
--- a/include/clang/Driver/Options.td
+++ b/include/clang/Driver/Options.td
@@ -1487,6 +1487,12 @@ def fstrict_return : Flag<["-"], "fstrict-return">, Group<f_Group>,
def fno_strict_return : Flag<["-"], "fno-strict-return">, Group<f_Group>,
Flags<[CC1Option]>;
+def fallow_editor_placeholders : Flag<["-"], "fallow-editor-placeholders">,
+ Group<f_Group>, Flags<[CC1Option]>,
+ HelpText<"Treat editor placeholders as valid source code">;
+def fno_allow_editor_placeholders : Flag<["-"],
+ "fno-allow-editor-placeholders">, Group<f_Group>;
+
def fdebug_types_section: Flag <["-"], "fdebug-types-section">, Group<f_Group>,
Flags<[CC1Option]>, HelpText<"Place debug types in their own section (ELF Only)">;
def fno_debug_types_section: Flag<["-"], "fno-debug-types-section">, Group<f_Group>,
diff --git a/include/clang/Lex/Lexer.h b/include/clang/Lex/Lexer.h
index 830c25a2e4..6ac6316d12 100644
--- a/include/clang/Lex/Lexer.h
+++ b/include/clang/Lex/Lexer.h
@@ -638,6 +638,8 @@ private:
bool IsStartOfConflictMarker(const char *CurPtr);
bool HandleEndOfConflictMarker(const char *CurPtr);
+ bool lexEditorPlaceholder(Token &Result, const char *CurPtr);
+
bool isCodeCompletionPoint(const char *CurPtr) const;
void cutOffLexing() { BufferPtr = BufferEnd; }
diff --git a/include/clang/Lex/Token.h b/include/clang/Lex/Token.h
index 4393e205ff..02a1fef70f 100644
--- a/include/clang/Lex/Token.h
+++ b/include/clang/Lex/Token.h
@@ -84,6 +84,7 @@ public:
StringifiedInMacro = 0x100, // This string or character literal is formed by
// macro stringizing or charizing operator.
CommaAfterElided = 0x200, // The comma following this token was elided (MS).
+ IsEditorPlaceholder = 0x400, // This identifier is a placeholder.
};
tok::TokenKind getKind() const { return Kind; }
@@ -298,6 +299,13 @@ public:
/// Returns true if the comma after this token was elided.
bool commaAfterElided() const { return getFlag(CommaAfterElided); }
+
+ /// Returns true if this token is an editor placeholder.
+ ///
+ /// Editor placeholders are produced by the code-completion engine and are
+ /// represented as characters between '<#' and '#>' in the source code. The
+ /// lexer uses identifier tokens to represent placeholders.
+ bool isEditorPlaceholder() const { return getFlag(IsEditorPlaceholder); }
};
/// \brief Information about the conditional stack (\#if directives)