From 209dfbe638d8a2ea85eac255a919381962b80704 Mon Sep 17 00:00:00 2001 From: Argyrios Kyrtzidis Date: Wed, 12 Oct 2011 17:36:33 +0000 Subject: [PATCH] Handle the case where preprocessor entities are not received in order, fixes http://llvm.org/PR11120 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@141788 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Lex/PreprocessingRecord.cpp | 30 +++++++++++++++++++++++++----- test/Preprocessor/pp-record.c | 9 +++++++++ test/Preprocessor/pp-record.h | 1 + 3 files changed, 35 insertions(+), 5 deletions(-) create mode 100644 test/Preprocessor/pp-record.c create mode 100644 test/Preprocessor/pp-record.h diff --git a/lib/Lex/PreprocessingRecord.cpp b/lib/Lex/PreprocessingRecord.cpp index 0f5577520d..2816609d5f 100644 --- a/lib/Lex/PreprocessingRecord.cpp +++ b/lib/Lex/PreprocessingRecord.cpp @@ -170,11 +170,31 @@ unsigned PreprocessingRecord::findEndLocalPreprocessedEntity( void PreprocessingRecord::addPreprocessedEntity(PreprocessedEntity *Entity) { assert(Entity); - assert((PreprocessedEntities.empty() || - !SourceMgr.isBeforeInTranslationUnit(Entity->getSourceRange().getBegin(), - PreprocessedEntities.back()->getSourceRange().getBegin())) && - "Adding a preprocessed entity that is before the previous one in TU"); - PreprocessedEntities.push_back(Entity); + SourceLocation BeginLoc = Entity->getSourceRange().getBegin(); + + // Check normal case, this entity begin location is after the previous one. + if (PreprocessedEntities.empty() || + !SourceMgr.isBeforeInTranslationUnit(BeginLoc, + PreprocessedEntities.back()->getSourceRange().getBegin())) { + PreprocessedEntities.push_back(Entity); + return; + } + + // The entity's location is not after the previous one; this can happen rarely + // e.g. with "#include MACRO". + // Iterate the entities vector in reverse until we find the right place to + // insert the new entity. + for (std::vector::iterator + RI = PreprocessedEntities.end(), Begin = PreprocessedEntities.begin(); + RI != Begin; --RI) { + std::vector::iterator I = RI; + --I; + if (!SourceMgr.isBeforeInTranslationUnit(BeginLoc, + (*I)->getSourceRange().getBegin())) { + PreprocessedEntities.insert(RI, Entity); + return; + } + } } void PreprocessingRecord::SetExternalSource( diff --git a/test/Preprocessor/pp-record.c b/test/Preprocessor/pp-record.c new file mode 100644 index 0000000000..dcb52b56b7 --- /dev/null +++ b/test/Preprocessor/pp-record.c @@ -0,0 +1,9 @@ +// RUN: %clang_cc1 -fsyntax-only -detailed-preprocessing-record %s + +// http://llvm.org/PR11120 + +#define FILE_HEADER_NAME "pp-record.h" + +#if defined(FILE_HEADER_NAME) +#include FILE_HEADER_NAME +#endif diff --git a/test/Preprocessor/pp-record.h b/test/Preprocessor/pp-record.h new file mode 100644 index 0000000000..34158bd205 --- /dev/null +++ b/test/Preprocessor/pp-record.h @@ -0,0 +1 @@ +// Only useful for #inclusion. -- 2.40.0