diff options
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/Frontend/ASTUnit.cpp | 4 | ||||
-rw-r--r-- | clang/lib/Lex/PPExpressions.cpp | 6 | ||||
-rw-r--r-- | clang/lib/Lex/PPMacroExpansion.cpp | 8 | ||||
-rw-r--r-- | clang/lib/Parse/Parser.cpp | 15 | ||||
-rw-r--r-- | clang/lib/Sema/SemaCodeComplete.cpp | 43 |
5 files changed, 69 insertions, 7 deletions
diff --git a/clang/lib/Frontend/ASTUnit.cpp b/clang/lib/Frontend/ASTUnit.cpp index 384edb4502b..117d3775c0e 100644 --- a/clang/lib/Frontend/ASTUnit.cpp +++ b/clang/lib/Frontend/ASTUnit.cpp @@ -278,7 +278,8 @@ void ASTUnit::CacheCodeCompletionResults() { | (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 @@ void CalculateHiddenNames(const CodeCompletionContext &Context, 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; } diff --git a/clang/lib/Lex/PPExpressions.cpp b/clang/lib/Lex/PPExpressions.cpp index 73f3d4ee7a0..163e869400a 100644 --- a/clang/lib/Lex/PPExpressions.cpp +++ b/clang/lib/Lex/PPExpressions.cpp @@ -149,6 +149,12 @@ static bool EvaluateValue(PPValue &Result, Token &PeekTok, DefinedTracker &DT, 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. diff --git a/clang/lib/Lex/PPMacroExpansion.cpp b/clang/lib/Lex/PPMacroExpansion.cpp index ad05b40e42a..894dc368e4c 100644 --- a/clang/lib/Lex/PPMacroExpansion.cpp +++ b/clang/lib/Lex/PPMacroExpansion.cpp @@ -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 @@ MacroArgs *Preprocessor::ReadFunctionLikeMacroArgs(Token &MacroName, // 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. diff --git a/clang/lib/Parse/Parser.cpp b/clang/lib/Parse/Parser.cpp index 13db742f18f..dd244bb895a 100644 --- a/clang/lib/Parse/Parser.cpp +++ b/clang/lib/Parse/Parser.cpp @@ -1133,7 +1133,7 @@ void Parser::FieldCallback::_anchor() { // 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::CodeCompleteInConditionalExclusion() { } 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); } diff --git a/clang/lib/Sema/SemaCodeComplete.cpp b/clang/lib/Sema/SemaCodeComplete.cpp index 06e65784e85..e25a47c2a55 100644 --- a/clang/lib/Sema/SemaCodeComplete.cpp +++ b/clang/lib/Sema/SemaCodeComplete.cpp @@ -4608,7 +4608,7 @@ void Sema::CodeCompleteObjCMethodDeclSelector(Scope *S, 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::CodeCompletePreprocessorDirective(Scope *S, bool InConditional) { } 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 @@ void Sema::CodeCompletePreprocessorMacroName(Scope *S, bool IsDefinition) { 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); |