From 9ef53ceb51939e1191a18d6f77ba3fea19e25335 Mon Sep 17 00:00:00 2001 From: Argyrios Kyrtzidis Date: Wed, 9 Apr 2014 18:21:23 +0000 Subject: [PATCH] [Preprocessor/CodeComplete] Don't add include guard macros to code-completion results. llvm-svn: 205917 --- clang/include/clang/Lex/MacroInfo.h | 8 ++++++++ clang/lib/Lex/MacroInfo.cpp | 3 ++- clang/lib/Lex/PPLexerChange.cpp | 4 ++++ clang/lib/Sema/SemaCodeComplete.cpp | 7 ++++++- clang/lib/Serialization/ASTReader.cpp | 1 + clang/lib/Serialization/ASTWriter.cpp | 1 + clang/test/Index/complete-macros.c | 23 +++++++++++++---------- clang/test/Index/complete-macros.h | 6 ++++++ 8 files changed, 41 insertions(+), 12 deletions(-) create mode 100644 clang/test/Index/complete-macros.h diff --git a/clang/include/clang/Lex/MacroInfo.h b/clang/include/clang/Lex/MacroInfo.h index 1580d1b693d8..cfbb376c16c8 100644 --- a/clang/include/clang/Lex/MacroInfo.h +++ b/clang/include/clang/Lex/MacroInfo.h @@ -104,6 +104,9 @@ private: /// \brief Whether this macro info was loaded from an AST file. unsigned FromASTFile : 1; + /// \brief Whether this macro was used as header guard. + bool UsedForHeaderGuard : 1; + ~MacroInfo() { assert(ArgumentList == 0 && "Didn't call destroy before dtor!"); } @@ -282,6 +285,11 @@ public: /// a precompiled header or module) rather than having been parsed. bool isFromASTFile() const { return FromASTFile; } + /// \brief Determine whether this macro was used for a header guard. + bool isUsedForHeaderGuard() const { return UsedForHeaderGuard; } + + void setUsedForHeaderGuard(bool Val) { UsedForHeaderGuard = Val; } + /// \brief Retrieve the global ID of the module that owns this particular /// macro info. unsigned getOwningModuleID() const { diff --git a/clang/lib/Lex/MacroInfo.cpp b/clang/lib/Lex/MacroInfo.cpp index 0325a80c3bea..8547ad3f72fc 100644 --- a/clang/lib/Lex/MacroInfo.cpp +++ b/clang/lib/Lex/MacroInfo.cpp @@ -29,7 +29,8 @@ MacroInfo::MacroInfo(SourceLocation DefLoc) IsUsed(false), IsAllowRedefinitionsWithoutWarning(false), IsWarnIfUnused(false), - FromASTFile(false) { + FromASTFile(false), + UsedForHeaderGuard(false) { } unsigned MacroInfo::getDefinitionLengthSlow(SourceManager &SM) const { diff --git a/clang/lib/Lex/PPLexerChange.cpp b/clang/lib/Lex/PPLexerChange.cpp index 949cd632620e..0b1be09d8726 100644 --- a/clang/lib/Lex/PPLexerChange.cpp +++ b/clang/lib/Lex/PPLexerChange.cpp @@ -284,6 +284,10 @@ bool Preprocessor::HandleEndOfFile(Token &Result, bool isEndOfMacro) { if (const FileEntry *FE = SourceMgr.getFileEntryForID(CurPPLexer->getFileID())) { HeaderInfo.SetFileControllingMacro(FE, ControllingMacro); + if (MacroInfo *MI = + getMacroInfo(const_cast(ControllingMacro))) { + MI->UsedForHeaderGuard = true; + } if (const IdentifierInfo *DefinedMacro = CurPPLexer->MIOpt.GetDefinedMacro()) { if (!ControllingMacro->hasMacroDefinition() && diff --git a/clang/lib/Sema/SemaCodeComplete.cpp b/clang/lib/Sema/SemaCodeComplete.cpp index d44c04b48094..38f7967f9f81 100644 --- a/clang/lib/Sema/SemaCodeComplete.cpp +++ b/clang/lib/Sema/SemaCodeComplete.cpp @@ -2987,11 +2987,16 @@ static void AddMacroResults(Preprocessor &PP, ResultBuilder &Results, for (Preprocessor::macro_iterator M = PP.macro_begin(), MEnd = PP.macro_end(); M != MEnd; ++M) { - if (IncludeUndefined || M->first->hasMacroDefinition()) + if (IncludeUndefined || M->first->hasMacroDefinition()) { + if (MacroInfo *MI = M->second->getMacroInfo()) + if (MI->isUsedForHeaderGuard()) + continue; + Results.AddResult(Result(M->first, getMacroUsagePriority(M->first->getName(), PP.getLangOpts(), TargetTypeIsPointer))); + } } Results.ExitScope(); diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp index 67c917bba49a..c16bc336da18 100644 --- a/clang/lib/Serialization/ASTReader.cpp +++ b/clang/lib/Serialization/ASTReader.cpp @@ -1271,6 +1271,7 @@ MacroInfo *ASTReader::ReadMacroRecord(ModuleFile &F, uint64_t Offset) { MacroInfo *MI = PP.AllocateDeserializedMacroInfo(Loc, SubModID); MI->setDefinitionEndLoc(ReadSourceLocation(F, Record, NextIndex)); MI->setIsUsed(Record[NextIndex++]); + MI->setUsedForHeaderGuard(Record[NextIndex++]); if (RecType == PP_MACRO_FUNCTION_LIKE) { // Decode function-like macro info. diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp index e4b5cdb9685f..99f0b5c56628 100644 --- a/clang/lib/Serialization/ASTWriter.cpp +++ b/clang/lib/Serialization/ASTWriter.cpp @@ -2003,6 +2003,7 @@ void ASTWriter::WritePreprocessor(const Preprocessor &PP, bool IsModule) { AddSourceLocation(MI->getDefinitionLoc(), Record); AddSourceLocation(MI->getDefinitionEndLoc(), Record); Record.push_back(MI->isUsed()); + Record.push_back(MI->isUsedForHeaderGuard()); unsigned Code; if (MI->isObjectLike()) { Code = PP_MACRO_OBJECT_LIKE; diff --git a/clang/test/Index/complete-macros.c b/clang/test/Index/complete-macros.c index 6d27b449ae2b..c81c8caad8d4 100644 --- a/clang/test/Index/complete-macros.c +++ b/clang/test/Index/complete-macros.c @@ -1,5 +1,5 @@ -// Note: the run lines follow their respective tests, since line/column -// matter in this test. +#include "complete-macros.h" +// 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 @@ -25,20 +25,23 @@ void test_variadic() { } -// RUN: c-index-test -code-completion-at=%s:7:1 %s | FileCheck -check-prefix=CHECK-CC0 %s +// RUN: c-index-test -code-completion-at=%s:7:1 %s -I%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 +// RUN: env CINDEXTEST_EDITING=1 CINDEXTEST_COMPLETION_CACHING=1 c-index-test -code-completion-at=%s:7:1 %s -I%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 -// RUN: c-index-test -code-completion-at=%s:14:8 %s | FileCheck -check-prefix=CHECK-CC2 %s -// RUN: env CINDEXTEST_EDITING=1 CINDEXTEST_COMPLETION_CACHING=1 c-index-test -code-completion-at=%s:14:8 %s | FileCheck -check-prefix=CHECK-CC2 %s +// RUN: c-index-test -code-completion-at=%s:13:13 %s -I%S | FileCheck -check-prefix=CHECK-CC2 %s +// RUN: c-index-test -code-completion-at=%s:14:8 %s -I%S | FileCheck -check-prefix=CHECK-CC2 %s +// RUN: env CINDEXTEST_EDITING=1 CINDEXTEST_COMPLETION_CACHING=1 c-index-test -code-completion-at=%s:14:8 %s -I%S | FileCheck -check-prefix=CHECK-CC2 %s // CHECK-CC2: macro definition:{TypedText nil} (32) -// RUN: c-index-test -code-completion-at=%s:15:5 %s | FileCheck -check-prefix=CHECK-CC3 %s -// RUN: env CINDEXTEST_EDITING=1 CINDEXTEST_COMPLETION_CACHING=1 c-index-test -code-completion-at=%s:15:5 %s | FileCheck -check-prefix=CHECK-CC3 %s +// RUN: c-index-test -code-completion-at=%s:15:5 %s -I%S | FileCheck -check-prefix=CHECK-CC3 %s +// RUN: env CINDEXTEST_EDITING=1 CINDEXTEST_COMPLETION_CACHING=1 c-index-test -code-completion-at=%s:15:5 %s -I%S | FileCheck -check-prefix=CHECK-CC3 %s // CHECK-CC3: macro definition:{TypedText nil} (65) -// RUN: env CINDEXTEST_EDITING=1 CINDEXTEST_COMPLETION_CACHING=1 c-index-test -code-completion-at=%s:25:2 %s | FileCheck -check-prefix=CHECK-VARIADIC %s +// RUN: env CINDEXTEST_EDITING=1 CINDEXTEST_COMPLETION_CACHING=1 c-index-test -code-completion-at=%s:25:2 %s -I%S | FileCheck -check-prefix=CHECK-VARIADIC %s // CHECK-VARIADIC: macro definition:{TypedText variadic1}{LeftParen (}{Placeholder ...}{RightParen )} (70) // CHECK-VARIADIC: macro definition:{TypedText variadic2}{LeftParen (}{Placeholder args...}{RightParen )} (70) // CHECK-VARIADIC: macro definition:{TypedText variadic3}{LeftParen (}{Placeholder args, ...}{RightParen )} (70) // CHECK-VARIADIC: macro definition:{TypedText variadic4}{LeftParen (}{Placeholder first}{Comma , }{Placeholder second}{Comma , }{Placeholder args, ...}{RightParen )} (70) // CHECK-VARIADIC: macro definition:{TypedText variadic5}{LeftParen (}{Placeholder first}{Comma , }{Placeholder second}{Comma , }{Placeholder args...}{RightParen )} (70) + +// RUN: env CINDEXTEST_EDITING=1 CINDEXTEST_COMPLETION_CACHING=1 c-index-test -code-completion-at=%s:15:5 %s -I%S | FileCheck -check-prefix=CHECK-CC4 %s +// CHECK-CC4-NOT: COMPLETE_MACROS_H_GUARD diff --git a/clang/test/Index/complete-macros.h b/clang/test/Index/complete-macros.h new file mode 100644 index 000000000000..70f49e31a1e3 --- /dev/null +++ b/clang/test/Index/complete-macros.h @@ -0,0 +1,6 @@ +#ifndef COMPLETE_MACROS_H_GUARD +#define COMPLETE_MACROS_H_GUARD + +void in_header(int); + +#endif