summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2014-03-23 00:27:18 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2014-03-23 00:27:18 +0000
commit04d05b5fa7fd19ae79ec9e9b9dd9ec7a5a68d879 (patch)
treeb481d7fe81caf3341d137495defdfd5847c7370a
parent957a2944dfce0672e349516dc5ae3b6474fb71db (diff)
downloadbcm5719-llvm-04d05b5fa7fd19ae79ec9e9b9dd9ec7a5a68d879.tar.gz
bcm5719-llvm-04d05b5fa7fd19ae79ec9e9b9dd9ec7a5a68d879.zip
If an update record makes a declaration interesting, pass it to the consumer.
llvm-svn: 204550
-rw-r--r--clang/lib/Serialization/ASTReader.cpp28
-rw-r--r--clang/lib/Serialization/ASTReaderDecl.cpp12
-rw-r--r--clang/test/Modules/Inputs/cxx-irgen-left.h4
-rw-r--r--clang/test/Modules/Inputs/cxx-irgen-top.h4
-rw-r--r--clang/test/Modules/cxx-irgen.cpp9
5 files changed, 39 insertions, 18 deletions
diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp
index abb6c9cc399..fc8c030833e 100644
--- a/clang/lib/Serialization/ASTReader.cpp
+++ b/clang/lib/Serialization/ASTReader.cpp
@@ -2892,6 +2892,7 @@ bool ASTReader::ReadASTBlock(ModuleFile &F) {
Error("invalid DECL_UPDATE_OFFSETS block in AST file");
return true;
}
+ // FIXME: If we've already loaded the decl, perform the updates now.
for (unsigned I = 0, N = Record.size(); I != N; I += 2)
DeclUpdateOffsets[getGlobalDeclID(F, Record[I])]
.push_back(std::make_pair(&F, Record[I+1]));
@@ -6313,6 +6314,15 @@ static void PassObjCImplDeclToConsumer(ObjCImplDecl *ImplD,
void ASTReader::PassInterestingDeclsToConsumer() {
assert(Consumer);
+
+ if (PassingDeclsToConsumer)
+ return;
+
+ // Guard variable to avoid recursively redoing the process of passing
+ // decls to consumer.
+ SaveAndRestore<bool> GuardPassingDeclsToConsumer(PassingDeclsToConsumer,
+ true);
+
while (!InterestingDecls.empty()) {
Decl *D = InterestingDecls.front();
InterestingDecls.pop_front();
@@ -7922,20 +7932,10 @@ void ASTReader::FinishedDeserializing() {
}
--NumCurrentElementsDeserializing;
- if (NumCurrentElementsDeserializing == 0 &&
- Consumer && !PassingDeclsToConsumer) {
- // Guard variable to avoid recursively redoing the process of passing
- // decls to consumer.
- SaveAndRestore<bool> GuardPassingDeclsToConsumer(PassingDeclsToConsumer,
- true);
-
- while (!InterestingDecls.empty()) {
- // We are not in recursive loading, so it's safe to pass the "interesting"
- // decls to the consumer.
- Decl *D = InterestingDecls.front();
- InterestingDecls.pop_front();
- PassInterestingDeclToConsumer(D);
- }
+ if (NumCurrentElementsDeserializing == 0 && Consumer) {
+ // We are not in recursive loading, so it's safe to pass the "interesting"
+ // decls to the consumer.
+ PassInterestingDeclsToConsumer();
}
}
diff --git a/clang/lib/Serialization/ASTReaderDecl.cpp b/clang/lib/Serialization/ASTReaderDecl.cpp
index d6660e8b9b4..5596bb4e748 100644
--- a/clang/lib/Serialization/ASTReaderDecl.cpp
+++ b/clang/lib/Serialization/ASTReaderDecl.cpp
@@ -2644,6 +2644,7 @@ void ASTReader::loadDeclUpdateRecords(serialization::DeclID ID, Decl *D) {
DeclUpdateOffsetsMap::iterator UpdI = DeclUpdateOffsets.find(ID);
if (UpdI != DeclUpdateOffsets.end()) {
FileOffsetsTy &UpdateOffsets = UpdI->second;
+ bool WasInteresting = isConsumerInterestedIn(D, false);
for (FileOffsetsTy::iterator
I = UpdateOffsets.begin(), E = UpdateOffsets.end(); I != E; ++I) {
ModuleFile *F = I->first;
@@ -2656,10 +2657,18 @@ void ASTReader::loadDeclUpdateRecords(serialization::DeclID ID, Decl *D) {
unsigned RecCode = Cursor.readRecord(Code, Record);
(void)RecCode;
assert(RecCode == DECL_UPDATES && "Expected DECL_UPDATES record!");
-
+
unsigned Idx = 0;
ASTDeclReader Reader(*this, *F, ID, 0, Record, Idx);
Reader.UpdateDecl(D, *F, Record);
+
+ // We might have made this declaration interesting. If so, remember that
+ // we need to hand it off to the consumer.
+ if (!WasInteresting &&
+ isConsumerInterestedIn(D, Reader.hasPendingBody())) {
+ InterestingDecls.push_back(D);
+ WasInteresting = true;
+ }
}
}
}
@@ -2958,6 +2967,7 @@ void ASTDeclReader::UpdateDecl(Decl *D, ModuleFile &ModuleFile,
Reader.ReadCXXCtorInitializers(ModuleFile, Record, Idx);
// Store the offset of the body so we can lazily load it later.
Reader.PendingBodies[FD] = GetCurrentCursorOffset();
+ HasPendingBody = true;
assert(Idx == Record.size() && "lazy body must be last");
break;
}
diff --git a/clang/test/Modules/Inputs/cxx-irgen-left.h b/clang/test/Modules/Inputs/cxx-irgen-left.h
index d2f9d7fe102..970ac764fc4 100644
--- a/clang/test/Modules/Inputs/cxx-irgen-left.h
+++ b/clang/test/Modules/Inputs/cxx-irgen-left.h
@@ -1,3 +1,7 @@
#include "cxx-irgen-top.h"
S<int> s;
+
+inline int instantiate_min() {
+ return min(1, 2);
+}
diff --git a/clang/test/Modules/Inputs/cxx-irgen-top.h b/clang/test/Modules/Inputs/cxx-irgen-top.h
index 05f8e19ee1b..8113e94def5 100644
--- a/clang/test/Modules/Inputs/cxx-irgen-top.h
+++ b/clang/test/Modules/Inputs/cxx-irgen-top.h
@@ -4,3 +4,7 @@ template<typename T> struct S {
};
extern template struct S<int>;
+
+template<typename T> T min(T a, T b) { return a < b ? a : b; }
+
+extern decltype(min(1, 2)) instantiate_min_decl;
diff --git a/clang/test/Modules/cxx-irgen.cpp b/clang/test/Modules/cxx-irgen.cpp
index 91657fdc0eb..7a42cb6b8c7 100644
--- a/clang/test/Modules/cxx-irgen.cpp
+++ b/clang/test/Modules/cxx-irgen.cpp
@@ -1,15 +1,18 @@
// RUN: rm -rf %t
-// RUN: %clang_cc1 -fmodules -x objective-c++ -fmodules-cache-path=%t -I %S/Inputs -triple %itanium_abi_triple -disable-llvm-optzns -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -fmodules -x objective-c++ -std=c++11 -fmodules-cache-path=%t -I %S/Inputs -triple %itanium_abi_triple -disable-llvm-optzns -emit-llvm -o - %s | FileCheck %s
// FIXME: When we have a syntax for modules in C++, use that.
@import cxx_irgen_top;
@import cxx_irgen_left;
@import cxx_irgen_right;
-// CHECK: define available_externally hidden i32 @_ZN1SIiE1gEv({{.*}} #[[ALWAYS_INLINE:.*]] align
+// CHECK-DAG: define available_externally hidden i32 @_ZN1SIiE1gEv({{.*}} #[[ALWAYS_INLINE:.*]] align
int a = S<int>::g();
-// CHECK: define available_externally i32 @_ZN1SIiE1fEv({{.*}} #[[ALWAYS_INLINE]] align
+// CHECK-DAG: define available_externally i32 @_ZN1SIiE1fEv({{.*}} #[[ALWAYS_INLINE]] align
int b = h();
+// CHECK-DAG: define linkonce_odr i32 @_Z3minIiET_S0_S0_(i32
+int c = min(1, 2);
+
// CHECK: attributes #[[ALWAYS_INLINE]] = {{.*}} alwaysinline
OpenPOWER on IntegriCloud