[cfe-commits] r111976 - in /cfe/trunk: include/clang/Lex/CodeCompletionHandler.h include/clang/Parse/Parser.h include/clang/Sema/Action.h include/clang/Sema/CodeCompleteConsumer.h include/clang/Sema/Sema.h lib/Frontend/ASTUnit.cpp lib/Lex/PPExpressions.cpp lib/Lex/PPMacroExpansion.cpp lib/Parse/Parser.cpp lib/Sema/SemaCodeComplete.cpp test/Index/complete-preprocessor.m
Douglas Gregor
dgregor at apple.com
Tue Aug 24 15:20:20 PDT 2010
Author: dgregor
Date: Tue Aug 24 17:20:20 2010
New Revision: 111976
URL: http://llvm.org/viewvc/llvm-project?rev=111976&view=rev
Log:
Implement code completion for preprocessor expressions and in macro
arguments.
Modified:
cfe/trunk/include/clang/Lex/CodeCompletionHandler.h
cfe/trunk/include/clang/Parse/Parser.h
cfe/trunk/include/clang/Sema/Action.h
cfe/trunk/include/clang/Sema/CodeCompleteConsumer.h
cfe/trunk/include/clang/Sema/Sema.h
cfe/trunk/lib/Frontend/ASTUnit.cpp
cfe/trunk/lib/Lex/PPExpressions.cpp
cfe/trunk/lib/Lex/PPMacroExpansion.cpp
cfe/trunk/lib/Parse/Parser.cpp
cfe/trunk/lib/Sema/SemaCodeComplete.cpp
cfe/trunk/test/Index/complete-preprocessor.m
Modified: cfe/trunk/include/clang/Lex/CodeCompletionHandler.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Lex/CodeCompletionHandler.h?rev=111976&r1=111975&r2=111976&view=diff
==============================================================================
--- cfe/trunk/include/clang/Lex/CodeCompletionHandler.h (original)
+++ cfe/trunk/include/clang/Lex/CodeCompletionHandler.h Tue Aug 24 17:20:20 2010
@@ -16,6 +16,9 @@
namespace clang {
+class IdentifierInfo;
+class MacroInfo;
+
/// \brief Callback handler that receives notifications when performing code
/// completion within the preprocessor.
class CodeCompletionHandler {
@@ -42,6 +45,16 @@
/// \param IsDefinition Whether this is the definition of a macro, e.g.,
/// in a #define.
virtual void CodeCompleteMacroName(bool IsDefinition) { }
+
+ /// \brief Callback invoked when performing code completion in a preprocessor
+ /// expression, such as the condition of an #if or #elif directive.
+ virtual void CodeCompletePreprocessorExpression() { }
+
+ /// \brief Callback invoked when performing code completion inside a
+ /// function-like macro argument.
+ virtual void CodeCompleteMacroArgument(IdentifierInfo *Macro,
+ MacroInfo *MacroInfo,
+ unsigned ArgumentIndex) { }
};
}
Modified: cfe/trunk/include/clang/Parse/Parser.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Parser.h?rev=111976&r1=111975&r2=111976&view=diff
==============================================================================
--- cfe/trunk/include/clang/Parse/Parser.h (original)
+++ cfe/trunk/include/clang/Parse/Parser.h Tue Aug 24 17:20:20 2010
@@ -1536,6 +1536,10 @@
virtual void CodeCompleteDirective(bool InConditional);
virtual void CodeCompleteInConditionalExclusion();
virtual void CodeCompleteMacroName(bool IsDefinition);
+ virtual void CodeCompletePreprocessorExpression();
+ virtual void CodeCompleteMacroArgument(IdentifierInfo *Macro,
+ MacroInfo *MacroInfo,
+ unsigned ArgumentIndex);
};
} // end namespace clang
Modified: cfe/trunk/include/clang/Sema/Action.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Action.h?rev=111976&r1=111975&r2=111976&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/Action.h (original)
+++ cfe/trunk/include/clang/Sema/Action.h Tue Aug 24 17:20:20 2010
@@ -43,7 +43,8 @@
// Lex.
class Preprocessor;
class Token;
-
+ class MacroInfo;
+
/// Action - As the parser reads the input file and recognizes the productions
/// of the grammar, it invokes methods on this class to turn the parsed input
/// into something useful: e.g. a parse tree.
@@ -3207,9 +3208,8 @@
/// \brief Code completion for a preprocessor directive.
///
- /// \brief S The scope in which the preprocessor directive is being parsed.
/// \brief InConditional Whether we're inside a preprocessor conditional.
- virtual void CodeCompletePreprocessorDirective(Scope *S, bool InConditional) {
+ virtual void CodeCompletePreprocessorDirective(bool InConditional) {
}
/// \brief Code completion while in an area of the translation unit that was
@@ -3219,13 +3219,31 @@
/// \brief Code completion in the preprocessor where an already-defined
/// macro name is expected, e.g., an #ifdef or #undef.
///
- /// \param S The scope in which the macro name occurs.
- ///
/// \param IsDefinition Whether this code completion for a macro name occurs
/// in a definition of the macro (#define) or in another use that already
/// expects that the macro is defined (e.g., #undef or #ifdef).
- virtual void CodeCompletePreprocessorMacroName(Scope *S, bool IsDefinition) {
+ virtual void CodeCompletePreprocessorMacroName(bool IsDefinition) {
}
+
+ /// \brief Callback invoked when performing code completion in a preprocessor
+ /// expression, such as the condition of an #if or #elif directive.
+ virtual void CodeCompletePreprocessorExpression() { }
+
+ /// \brief Callback invoked when performing code completion inside a
+ /// function-like macro argument.
+ ///
+ /// \param S The scope in which this macro is being expanded.
+ ///
+ /// \param Macro The name of the macro that is going to be expanded.
+ ///
+ /// \param MacroInfo Information about the macro that is going to be
+ /// expanded.
+ ///
+ /// \param Argument The argument in which the code-completion token occurs.
+ virtual void CodeCompletePreprocessorMacroArgument(Scope *S,
+ IdentifierInfo *Macro,
+ MacroInfo *MacroInfo,
+ unsigned Argument) { }
//@}
};
Modified: cfe/trunk/include/clang/Sema/CodeCompleteConsumer.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/CodeCompleteConsumer.h?rev=111976&r1=111975&r2=111976&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/CodeCompleteConsumer.h (original)
+++ cfe/trunk/include/clang/Sema/CodeCompleteConsumer.h Tue Aug 24 17:20:20 2010
@@ -174,7 +174,9 @@
CCC_MacroName,
/// \brief Code completion occurred where a macro name is expected
/// (without any arguments, in the case of a function-like macro).
- CCC_MacroNameUse
+ CCC_MacroNameUse,
+ /// \brief Code completion occurred within a preprocessor expression.
+ CCC_PreprocessorExpression
};
private:
Modified: cfe/trunk/include/clang/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=111976&r1=111975&r2=111976&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/Sema.h (original)
+++ cfe/trunk/include/clang/Sema/Sema.h Tue Aug 24 17:20:20 2010
@@ -4633,9 +4633,14 @@
ParsedType ReturnType,
IdentifierInfo **SelIdents,
unsigned NumSelIdents);
- virtual void CodeCompletePreprocessorDirective(Scope *S, bool InConditional);
+ virtual void CodeCompletePreprocessorDirective(bool InConditional);
virtual void CodeCompleteInPreprocessorConditionalExclusion(Scope *S);
- virtual void CodeCompletePreprocessorMacroName(Scope *S, bool IsDefinition);
+ virtual void CodeCompletePreprocessorMacroName(bool IsDefinition);
+ virtual void CodeCompletePreprocessorExpression();
+ virtual void CodeCompletePreprocessorMacroArgument(Scope *S,
+ IdentifierInfo *Macro,
+ MacroInfo *MacroInfo,
+ unsigned Argument);
void GatherGlobalCodeCompletions(
llvm::SmallVectorImpl<CodeCompleteConsumer::Result> &Results);
//@}
Modified: cfe/trunk/lib/Frontend/ASTUnit.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/ASTUnit.cpp?rev=111976&r1=111975&r2=111976&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/ASTUnit.cpp (original)
+++ cfe/trunk/lib/Frontend/ASTUnit.cpp Tue Aug 24 17:20:20 2010
@@ -278,7 +278,8 @@
| (1 << (CodeCompletionContext::CCC_Statement - 1))
| (1 << (CodeCompletionContext::CCC_Expression - 1))
| (1 << (CodeCompletionContext::CCC_ObjCMessageReceiver - 1))
- | (1 << (CodeCompletionContext::CCC_MacroNameUse - 1));
+ | (1 << (CodeCompletionContext::CCC_MacroNameUse - 1))
+ | (1 << (CodeCompletionContext::CCC_PreprocessorExpression - 1));
CachedResult.Priority = Results[I].Priority;
CachedResult.Kind = Results[I].CursorKind;
@@ -1550,6 +1551,7 @@
case CodeCompletionContext::CCC_ObjCProtocolName:
case CodeCompletionContext::CCC_MacroName:
case CodeCompletionContext::CCC_MacroNameUse:
+ case CodeCompletionContext::CCC_PreprocessorExpression:
// If we're just looking for protocol or macro names, nothing can hide them.
return;
}
Modified: cfe/trunk/lib/Lex/PPExpressions.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/PPExpressions.cpp?rev=111976&r1=111975&r2=111976&view=diff
==============================================================================
--- cfe/trunk/lib/Lex/PPExpressions.cpp (original)
+++ cfe/trunk/lib/Lex/PPExpressions.cpp Tue Aug 24 17:20:20 2010
@@ -149,6 +149,12 @@
bool ValueLive, Preprocessor &PP) {
DT.State = DefinedTracker::Unknown;
+ if (PeekTok.is(tok::code_completion)) {
+ if (PP.getCodeCompletionHandler())
+ PP.getCodeCompletionHandler()->CodeCompletePreprocessorExpression();
+ PP.LexUnexpandedToken(PeekTok);
+ }
+
// If this token's spelling is a pp-identifier, check to see if it is
// 'defined' or if it is a macro. Note that we check here because many
// keywords are pp-identifiers, so we can't check the kind.
Modified: cfe/trunk/lib/Lex/PPMacroExpansion.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/PPMacroExpansion.cpp?rev=111976&r1=111975&r2=111976&view=diff
==============================================================================
--- cfe/trunk/lib/Lex/PPMacroExpansion.cpp (original)
+++ cfe/trunk/lib/Lex/PPMacroExpansion.cpp Tue Aug 24 17:20:20 2010
@@ -19,6 +19,7 @@
#include "clang/Basic/FileManager.h"
#include "clang/Basic/TargetInfo.h"
#include "clang/Lex/LexDiagnostic.h"
+#include "clang/Lex/CodeCompletionHandler.h"
#include "llvm/ADT/StringSwitch.h"
#include "llvm/Support/raw_ostream.h"
#include <cstdio>
@@ -323,6 +324,13 @@
// an argument value in a macro could expand to ',' or '(' or ')'.
LexUnexpandedToken(Tok);
+ if (Tok.is(tok::code_completion)) {
+ if (CodeComplete)
+ CodeComplete->CodeCompleteMacroArgument(MacroName.getIdentifierInfo(),
+ MI, NumActuals);
+ LexUnexpandedToken(Tok);
+ }
+
if (Tok.is(tok::eof) || Tok.is(tok::eom)) { // "#if f(<eof>" & "#if f(\n"
Diag(MacroName, diag::err_unterm_macro_invoc);
// Do not lose the EOF/EOM. Return it to the client.
Modified: cfe/trunk/lib/Parse/Parser.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/Parser.cpp?rev=111976&r1=111975&r2=111976&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/Parser.cpp (original)
+++ cfe/trunk/lib/Parse/Parser.cpp Tue Aug 24 17:20:20 2010
@@ -1133,7 +1133,7 @@
// Code-completion pass-through functions
void Parser::CodeCompleteDirective(bool InConditional) {
- Actions.CodeCompletePreprocessorDirective(getCurScope(), InConditional);
+ Actions.CodeCompletePreprocessorDirective(InConditional);
}
void Parser::CodeCompleteInConditionalExclusion() {
@@ -1141,5 +1141,16 @@
}
void Parser::CodeCompleteMacroName(bool IsDefinition) {
- Actions.CodeCompletePreprocessorMacroName(getCurScope(), IsDefinition);
+ Actions.CodeCompletePreprocessorMacroName(IsDefinition);
+}
+
+void Parser::CodeCompletePreprocessorExpression() {
+ Actions.CodeCompletePreprocessorExpression();
+}
+
+void Parser::CodeCompleteMacroArgument(IdentifierInfo *Macro,
+ MacroInfo *MacroInfo,
+ unsigned ArgumentIndex) {
+ Actions.CodeCompletePreprocessorMacroArgument(getCurScope(), Macro, MacroInfo,
+ ArgumentIndex);
}
Modified: cfe/trunk/lib/Sema/SemaCodeComplete.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaCodeComplete.cpp?rev=111976&r1=111975&r2=111976&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaCodeComplete.cpp (original)
+++ cfe/trunk/lib/Sema/SemaCodeComplete.cpp Tue Aug 24 17:20:20 2010
@@ -4608,7 +4608,7 @@
Results.data(),Results.size());
}
-void Sema::CodeCompletePreprocessorDirective(Scope *S, bool InConditional) {
+void Sema::CodeCompletePreprocessorDirective(bool InConditional) {
ResultBuilder Results(*this);
Results.EnterNewScope();
@@ -4785,11 +4785,12 @@
}
void Sema::CodeCompleteInPreprocessorConditionalExclusion(Scope *S) {
- CodeCompleteOrdinaryName(S, Action::PCC_RecoveryInFunction);
+ CodeCompleteOrdinaryName(S,
+ S->getFnParent()? Action::PCC_RecoveryInFunction
+ : Action::PCC_Namespace);
}
-void Sema::CodeCompletePreprocessorMacroName(Scope *S, bool IsDefinition) {
- typedef CodeCompleteConsumer::Result Result;
+void Sema::CodeCompletePreprocessorMacroName(bool IsDefinition) {
ResultBuilder Results(*this);
if (!IsDefinition && (!CodeCompleter || CodeCompleter->includeMacros())) {
// Add just the names of macros, not their arguments.
@@ -4812,6 +4813,40 @@
Results.data(), Results.size());
}
+void Sema::CodeCompletePreprocessorExpression() {
+ ResultBuilder Results(*this);
+
+ if (!CodeCompleter || CodeCompleter->includeMacros())
+ AddMacroResults(PP, Results);
+
+ // defined (<macro>)
+ Results.EnterNewScope();
+ CodeCompletionString *Pattern = new CodeCompletionString;
+ Pattern->AddTypedTextChunk("defined");
+ Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
+ Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
+ Pattern->AddPlaceholderChunk("macro");
+ Pattern->AddChunk(CodeCompletionString::CK_RightParen);
+ Results.AddResult(Pattern);
+ Results.ExitScope();
+
+ HandleCodeCompleteResults(this, CodeCompleter,
+ CodeCompletionContext::CCC_PreprocessorExpression,
+ Results.data(), Results.size());
+}
+
+void Sema::CodeCompletePreprocessorMacroArgument(Scope *S,
+ IdentifierInfo *Macro,
+ MacroInfo *MacroInfo,
+ unsigned Argument) {
+ // FIXME: In the future, we could provide "overload" results, much like we
+ // do for function calls.
+
+ CodeCompleteOrdinaryName(S,
+ S->getFnParent()? Action::PCC_RecoveryInFunction
+ : Action::PCC_Namespace);
+}
+
void Sema::GatherGlobalCodeCompletions(
llvm::SmallVectorImpl<CodeCompleteConsumer::Result> &Results) {
ResultBuilder Builder(*this);
Modified: cfe/trunk/test/Index/complete-preprocessor.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Index/complete-preprocessor.m?rev=111976&r1=111975&r2=111976&view=diff
==============================================================================
--- cfe/trunk/test/Index/complete-preprocessor.m (original)
+++ cfe/trunk/test/Index/complete-preprocessor.m Tue Aug 24 17:20:20 2010
@@ -11,6 +11,8 @@
#if defined(FOO)
#endif
+FOO(in,t) value;
+
// RUN: c-index-test -code-completion-at=%s:4:2 %s | FileCheck -check-prefix=CHECK-CC1 %s
// CHECK-CC1: NotImplemented:{TypedText define}{HorizontalSpace }{Placeholder macro} (30)
// CHECK-CC1-NEXT: NotImplemented:{TypedText define}{HorizontalSpace }{Placeholder macro}{LeftParen (}{Placeholder args}{RightParen )} (30)
@@ -55,3 +57,18 @@
// CHECK-CC3: NotImplemented:{TypedText FOO} (30)
// RUN: c-index-test -code-completion-at=%s:11:12 %s | FileCheck -check-prefix=CHECK-CC3 %s
// RUN: c-index-test -code-completion-at=%s:11:13 %s | FileCheck -check-prefix=CHECK-CC3 %s
+// RUN: c-index-test -code-completion-at=%s:11:5 %s | FileCheck -check-prefix=CHECK-CC4 %s
+// CHECK-CC4: macro definition:{TypedText BAR} (70)
+// CHECK-CC4: macro definition:{TypedText FOO}{LeftParen (}{Placeholder a}{Comma , }{Placeholder b}{RightParen )} (70)
+// RUN: c-index-test -code-completion-at=%s:14:5 %s | FileCheck -check-prefix=CHECK-CC5 %s
+// CHECK-CC5: NotImplemented:{TypedText const} (40)
+// CHECK-CC5: NotImplemented:{TypedText double} (40)
+// CHECK-CC5: NotImplemented:{TypedText enum} (40)
+// CHECK-CC5: NotImplemented:{TypedText extern} (30)
+// CHECK-CC5: NotImplemented:{TypedText float} (40)
+// CHECK-CC5: macro definition:{TypedText FOO}{LeftParen (}{Placeholder a}{Comma , }{Placeholder b}{RightParen )} (70)
+// CHECK-CC5: macro definition:{TypedText i386} (70)
+// CHECK-CC5: TypedefDecl:{TypedText id} (40)
+// CHECK-CC5: NotImplemented:{TypedText inline} (30)
+// CHECK-CC5: NotImplemented:{TypedText int} (40)
+// CHECK-CC5: NotImplemented:{TypedText long} (40)
More information about the cfe-commits
mailing list