erikjv created this revision. erikjv added a reviewer: bkramer. erikjv added a subscriber: cfe-commits.
Previously, a preamble only included #if blocks (and friends like #ifdef) if there was a corresponding #endif before any declaration or definition. The problem is that any header file that uses include guards will not have a preamble generated, which makes code-completion very slow. This fixes PR26045. http://reviews.llvm.org/D15994 Files: lib/Lex/Lexer.cpp test/Lexer/preamble.c test/Lexer/preamble2.c Index: test/Lexer/preamble2.c =================================================================== --- /dev/null +++ test/Lexer/preamble2.c @@ -0,0 +1,19 @@ +// Preamble detection test: header with an include guard. +#ifndef HEADER_H +#define HEADER_H +#include "foo" +int bar; +#endif + +// This test checks for detection of the preamble of a file, which +// includes all of the starting comments and #includes. + +// RUN: %clang_cc1 -print-preamble %s > %t +// RUN: echo END. >> %t +// RUN: FileCheck < %t %s + +// CHECK: // Preamble detection test: header with an include guard. +// CHECK-NEXT: #ifndef HEADER_H +// CHECK-NEXT: #define HEADER_H +// CHECK-NEXT: #include "foo" +// CHECK-NEXT: END. Index: test/Lexer/preamble.c =================================================================== --- test/Lexer/preamble.c +++ test/Lexer/preamble.c @@ -9,15 +9,12 @@ #pragma unknown #endif #ifdef WIBBLE -#include "honk" -#else -int foo(); +#include "foo" +int bar; #endif // This test checks for detection of the preamble of a file, which -// includes all of the starting comments and #includes. Note that any -// changes to the preamble part of this file must be mirrored in -// Inputs/preamble.txt, since we diff against it. +// includes all of the starting comments and #includes. // RUN: %clang_cc1 -print-preamble %s > %t // RUN: echo END. >> %t @@ -33,4 +30,6 @@ // CHECK-NEXT: #endif // CHECK-NEXT: #pragma unknown // CHECK-NEXT: #endif +// CHECK-NEXT: #ifdef WIBBLE +// CHECK-NEXT: #include "foo" // CHECK-NEXT: END. Index: lib/Lex/Lexer.cpp =================================================================== --- lib/Lex/Lexer.cpp +++ lib/Lex/Lexer.cpp @@ -552,7 +552,7 @@ bool InPreprocessorDirective = false; Token TheTok; Token IfStartTok; - unsigned IfCount = 0; + int IfCount = 0; SourceLocation ActiveCommentLoc; unsigned MaxLineOffset = 0; @@ -656,8 +656,10 @@ case PDK_EndIf: // Mismatched #endif. The preamble ends here. - if (IfCount == 0) + if (IfCount == 0) { + --IfCount; break; + } --IfCount; continue; @@ -682,7 +684,8 @@ } while (true); SourceLocation End; - if (IfCount) + if (IfCount < 0) // This allows for open #ifs, so a header with an include + // guard will have a preamble generated for it. End = IfStartTok.getLocation(); else if (ActiveCommentLoc.isValid()) End = ActiveCommentLoc; // don't truncate a decl comment.
Index: test/Lexer/preamble2.c =================================================================== --- /dev/null +++ test/Lexer/preamble2.c @@ -0,0 +1,19 @@ +// Preamble detection test: header with an include guard. +#ifndef HEADER_H +#define HEADER_H +#include "foo" +int bar; +#endif + +// This test checks for detection of the preamble of a file, which +// includes all of the starting comments and #includes. + +// RUN: %clang_cc1 -print-preamble %s > %t +// RUN: echo END. >> %t +// RUN: FileCheck < %t %s + +// CHECK: // Preamble detection test: header with an include guard. +// CHECK-NEXT: #ifndef HEADER_H +// CHECK-NEXT: #define HEADER_H +// CHECK-NEXT: #include "foo" +// CHECK-NEXT: END. Index: test/Lexer/preamble.c =================================================================== --- test/Lexer/preamble.c +++ test/Lexer/preamble.c @@ -9,15 +9,12 @@ #pragma unknown #endif #ifdef WIBBLE -#include "honk" -#else -int foo(); +#include "foo" +int bar; #endif // This test checks for detection of the preamble of a file, which -// includes all of the starting comments and #includes. Note that any -// changes to the preamble part of this file must be mirrored in -// Inputs/preamble.txt, since we diff against it. +// includes all of the starting comments and #includes. // RUN: %clang_cc1 -print-preamble %s > %t // RUN: echo END. >> %t @@ -33,4 +30,6 @@ // CHECK-NEXT: #endif // CHECK-NEXT: #pragma unknown // CHECK-NEXT: #endif +// CHECK-NEXT: #ifdef WIBBLE +// CHECK-NEXT: #include "foo" // CHECK-NEXT: END. Index: lib/Lex/Lexer.cpp =================================================================== --- lib/Lex/Lexer.cpp +++ lib/Lex/Lexer.cpp @@ -552,7 +552,7 @@ bool InPreprocessorDirective = false; Token TheTok; Token IfStartTok; - unsigned IfCount = 0; + int IfCount = 0; SourceLocation ActiveCommentLoc; unsigned MaxLineOffset = 0; @@ -656,8 +656,10 @@ case PDK_EndIf: // Mismatched #endif. The preamble ends here. - if (IfCount == 0) + if (IfCount == 0) { + --IfCount; break; + } --IfCount; continue; @@ -682,7 +684,8 @@ } while (true); SourceLocation End; - if (IfCount) + if (IfCount < 0) // This allows for open #ifs, so a header with an include + // guard will have a preamble generated for it. End = IfStartTok.getLocation(); else if (ActiveCommentLoc.isValid()) End = ActiveCommentLoc; // don't truncate a decl comment.
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits