зеркало из https://github.com/microsoft/clang-1.git
If a macro has been #undef'd in a precompiled header, we still need to
write out the macro history for that macro. Similarly, we need to cope with reading a macro definition that has been #undef'd. Take advantage of this new ability so that global code-completion results can refer to #undef'd macros, rather than losing them entirely. For multiply defined/#undef'd macros, we will still get the wrong result, but it's better than getting no result. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@165502 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
f5b132f7b3
Коммит
3644d97009
|
@ -147,6 +147,9 @@ public:
|
|||
bool hadMacroDefinition() const {
|
||||
return HadMacro;
|
||||
}
|
||||
void setHadMacroDefinition(bool Val) {
|
||||
HadMacro = Val;
|
||||
}
|
||||
|
||||
/// getTokenID - If this is a source-language token (e.g. 'for'), this API
|
||||
/// can be used to cause the lexer to map identifiers to source-language
|
||||
|
|
|
@ -2495,7 +2495,7 @@ CodeCompletionResult::CreateCodeCompletionString(ASTContext &Ctx,
|
|||
}
|
||||
|
||||
if (Kind == RK_Macro) {
|
||||
MacroInfo *MI = PP.getMacroInfo(Macro);
|
||||
MacroInfo *MI = PP.getMacroInfoHistory(Macro);
|
||||
assert(MI && "Not a macro?");
|
||||
|
||||
Result.AddTypedTextChunk(
|
||||
|
@ -2902,6 +2902,7 @@ CXCursorKind clang::getCursorKindForDecl(Decl *D) {
|
|||
}
|
||||
|
||||
static void AddMacroResults(Preprocessor &PP, ResultBuilder &Results,
|
||||
bool IncludeUndefined,
|
||||
bool TargetTypeIsPointer = false) {
|
||||
typedef CodeCompletionResult Result;
|
||||
|
||||
|
@ -2910,11 +2911,8 @@ static void AddMacroResults(Preprocessor &PP, ResultBuilder &Results,
|
|||
for (Preprocessor::macro_iterator M = PP.macro_begin(),
|
||||
MEnd = PP.macro_end();
|
||||
M != MEnd; ++M) {
|
||||
// FIXME: Eventually, we'd want to be able to look back to the macro
|
||||
// definition that was actually active at the point of code completion (even
|
||||
// if that macro has since been #undef'd).
|
||||
if (M->first->hasMacroDefinition())
|
||||
Results.AddResult(Result(M->first,
|
||||
if (IncludeUndefined || M->first->hasMacroDefinition())
|
||||
Results.AddResult(Result(M->first,
|
||||
getMacroUsagePriority(M->first->getName(),
|
||||
PP.getLangOpts(),
|
||||
TargetTypeIsPointer)));
|
||||
|
@ -3213,7 +3211,7 @@ void Sema::CodeCompleteOrdinaryName(Scope *S,
|
|||
}
|
||||
|
||||
if (CodeCompleter->includeMacros())
|
||||
AddMacroResults(PP, Results);
|
||||
AddMacroResults(PP, Results, false);
|
||||
|
||||
HandleCodeCompleteResults(this, CodeCompleter, Results.getCompletionContext(),
|
||||
Results.data(),Results.size());
|
||||
|
@ -3344,7 +3342,7 @@ void Sema::CodeCompleteExpression(Scope *S,
|
|||
AddPrettyFunctionResults(PP.getLangOpts(), Results);
|
||||
|
||||
if (CodeCompleter->includeMacros())
|
||||
AddMacroResults(PP, Results, PreferredTypeIsPointer);
|
||||
AddMacroResults(PP, Results, false, PreferredTypeIsPointer);
|
||||
HandleCodeCompleteResults(this, CodeCompleter,
|
||||
CodeCompletionContext(CodeCompletionContext::CCC_Expression,
|
||||
Data.PreferredType),
|
||||
|
@ -3736,7 +3734,7 @@ void Sema::CodeCompleteCase(Scope *S) {
|
|||
//so only say we include macros if the code completer says we do
|
||||
enum CodeCompletionContext::Kind kind = CodeCompletionContext::CCC_Other;
|
||||
if (CodeCompleter->includeMacros()) {
|
||||
AddMacroResults(PP, Results);
|
||||
AddMacroResults(PP, Results, false);
|
||||
kind = CodeCompletionContext::CCC_OtherWithMacros;
|
||||
}
|
||||
|
||||
|
@ -3959,7 +3957,7 @@ void Sema::CodeCompleteAfterIf(Scope *S) {
|
|||
AddPrettyFunctionResults(PP.getLangOpts(), Results);
|
||||
|
||||
if (CodeCompleter->includeMacros())
|
||||
AddMacroResults(PP, Results);
|
||||
AddMacroResults(PP, Results, false);
|
||||
|
||||
HandleCodeCompleteResults(this, CodeCompleter, Results.getCompletionContext(),
|
||||
Results.data(),Results.size());
|
||||
|
@ -4960,7 +4958,7 @@ void Sema::CodeCompleteObjCPassingType(Scope *S, ObjCDeclSpec &DS,
|
|||
CodeCompleter->includeGlobals());
|
||||
|
||||
if (CodeCompleter->includeMacros())
|
||||
AddMacroResults(PP, Results);
|
||||
AddMacroResults(PP, Results, false);
|
||||
|
||||
HandleCodeCompleteResults(this, CodeCompleter,
|
||||
CodeCompletionContext::CCC_Type,
|
||||
|
@ -5190,7 +5188,7 @@ void Sema::CodeCompleteObjCMessageReceiver(Scope *S) {
|
|||
Results.ExitScope();
|
||||
|
||||
if (CodeCompleter->includeMacros())
|
||||
AddMacroResults(PP, Results);
|
||||
AddMacroResults(PP, Results, false);
|
||||
HandleCodeCompleteResults(this, CodeCompleter, Results.getCompletionContext(),
|
||||
Results.data(), Results.size());
|
||||
|
||||
|
@ -7190,7 +7188,7 @@ void Sema::CodeCompletePreprocessorExpression() {
|
|||
CodeCompletionContext::CCC_PreprocessorExpression);
|
||||
|
||||
if (!CodeCompleter || CodeCompleter->includeMacros())
|
||||
AddMacroResults(PP, Results);
|
||||
AddMacroResults(PP, Results, true);
|
||||
|
||||
// defined (<macro>)
|
||||
Results.EnterNewScope();
|
||||
|
@ -7239,7 +7237,7 @@ void Sema::GatherGlobalCodeCompletions(CodeCompletionAllocator &Allocator,
|
|||
}
|
||||
|
||||
if (!CodeCompleter || CodeCompleter->includeMacros())
|
||||
AddMacroResults(PP, Builder);
|
||||
AddMacroResults(PP, Builder, true);
|
||||
|
||||
Results.clear();
|
||||
Results.insert(Results.end(),
|
||||
|
|
|
@ -1460,6 +1460,8 @@ void ASTReader::setIdentifierIsMacro(IdentifierInfo *II, ModuleFile &F,
|
|||
if (Visible) {
|
||||
// Note that this identifier has a macro definition.
|
||||
II->setHasMacroDefinition(true);
|
||||
} else {
|
||||
II->setHadMacroDefinition(true);
|
||||
}
|
||||
|
||||
// Adjust the offset to a global offset.
|
||||
|
|
|
@ -1698,14 +1698,13 @@ void ASTWriter::WritePreprocessor(const Preprocessor &PP, bool IsModule) {
|
|||
IdentifierInfo *Name
|
||||
= const_cast<IdentifierInfo *>(DeserializedMacroNames[I]);
|
||||
if (Name->hadMacroDefinition() && MacroDefinitionsSeen.insert(Name))
|
||||
MacrosToEmit.push_back(std::make_pair(Name, PP.getMacroInfo(Name)));
|
||||
MacrosToEmit.push_back(std::make_pair(Name,
|
||||
PP.getMacroInfoHistory(Name)));
|
||||
}
|
||||
|
||||
for (unsigned I = 0, N = MacrosToEmit.size(); I != N; ++I) {
|
||||
const IdentifierInfo *Name = MacrosToEmit[I].first;
|
||||
MacroInfo *MI = MacrosToEmit[I].second;
|
||||
if (!MI)
|
||||
continue;
|
||||
|
||||
// History of macro definitions for this identifier in chronological order.
|
||||
SmallVector<MacroInfo*, 8> MacroHistory;
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
// Note: the run lines follow their respective tests, since line/column
|
||||
// matter in this test.
|
||||
|
||||
#define FOO(Arg1,Arg2) foobar
|
||||
#define nil 0
|
||||
#undef FOO
|
||||
void f() {
|
||||
|
||||
}
|
||||
|
@ -25,7 +25,8 @@ void test_variadic() {
|
|||
|
||||
}
|
||||
|
||||
// RUN: c-index-test -code-completion-at=%s:7:1 %s | FileCheck -check-prefix=CHECK-CC1 %s
|
||||
// RUN: c-index-test -code-completion-at=%s:7:1 %s | FileCheck -check-prefix=CHECK-CC0 %s
|
||||
// CHECK-CC0-NOT: FOO
|
||||
// RUN: env CINDEXTEST_EDITING=1 CINDEXTEST_COMPLETION_CACHING=1 c-index-test -code-completion-at=%s:7:1 %s | FileCheck -check-prefix=CHECK-CC1 %s
|
||||
// CHECK-CC1: macro definition:{TypedText FOO}{LeftParen (}{Placeholder Arg1}{Comma , }{Placeholder Arg2}{RightParen )}
|
||||
// RUN: c-index-test -code-completion-at=%s:13:13 %s | FileCheck -check-prefix=CHECK-CC2 %s
|
||||
|
|
Загрузка…
Ссылка в новой задаче