summaryrefslogtreecommitdiffstats
path: root/clang
diff options
context:
space:
mode:
authorArgyrios Kyrtzidis <akyrtzi@gmail.com>2011-10-12 17:36:33 +0000
committerArgyrios Kyrtzidis <akyrtzi@gmail.com>2011-10-12 17:36:33 +0000
commitf37d0a61c09b90c5c112b62e679b66d0abba30d7 (patch)
tree01aea24d20937f5b11137382bfd02dfe591f92d7 /clang
parent84cf2b8c98e552f3b71ac7a12b1426c4843e1463 (diff)
downloadbcm5719-llvm-f37d0a61c09b90c5c112b62e679b66d0abba30d7.tar.gz
bcm5719-llvm-f37d0a61c09b90c5c112b62e679b66d0abba30d7.zip
Handle the case where preprocessor entities are not received in order,
fixes http://llvm.org/PR11120 llvm-svn: 141788
Diffstat (limited to 'clang')
-rw-r--r--clang/lib/Lex/PreprocessingRecord.cpp30
-rw-r--r--clang/test/Preprocessor/pp-record.c9
-rw-r--r--clang/test/Preprocessor/pp-record.h1
3 files changed, 35 insertions, 5 deletions
diff --git a/clang/lib/Lex/PreprocessingRecord.cpp b/clang/lib/Lex/PreprocessingRecord.cpp
index 0f5577520d6..2816609d5f8 100644
--- a/clang/lib/Lex/PreprocessingRecord.cpp
+++ b/clang/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<PreprocessedEntity *>::iterator
+ RI = PreprocessedEntities.end(), Begin = PreprocessedEntities.begin();
+ RI != Begin; --RI) {
+ std::vector<PreprocessedEntity *>::iterator I = RI;
+ --I;
+ if (!SourceMgr.isBeforeInTranslationUnit(BeginLoc,
+ (*I)->getSourceRange().getBegin())) {
+ PreprocessedEntities.insert(RI, Entity);
+ return;
+ }
+ }
}
void PreprocessingRecord::SetExternalSource(
diff --git a/clang/test/Preprocessor/pp-record.c b/clang/test/Preprocessor/pp-record.c
new file mode 100644
index 00000000000..dcb52b56b7d
--- /dev/null
+++ b/clang/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/clang/test/Preprocessor/pp-record.h b/clang/test/Preprocessor/pp-record.h
new file mode 100644
index 00000000000..34158bd2052
--- /dev/null
+++ b/clang/test/Preprocessor/pp-record.h
@@ -0,0 +1 @@
+// Only useful for #inclusion.
OpenPOWER on IntegriCloud