Support #pragma weak for PCH.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@110323 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/include/clang/Frontend/PCHBitCodes.h b/include/clang/Frontend/PCHBitCodes.h
index a07060f..3733796 100644
--- a/include/clang/Frontend/PCHBitCodes.h
+++ b/include/clang/Frontend/PCHBitCodes.h
@@ -250,7 +250,10 @@
REDECLS_UPDATE_LATEST = 29,
/// \brief Record code for declarations that Sema keeps references of.
- SEMA_DECL_REFS = 30
+ SEMA_DECL_REFS = 30,
+
+ /// \brief Record code for weak undeclared identifiers.
+ WEAK_UNDECLARED_IDENTIFIERS = 31
};
/// \brief Record types used within a source manager block.
diff --git a/include/clang/Frontend/PCHReader.h b/include/clang/Frontend/PCHReader.h
index f7690fb..76975a0 100644
--- a/include/clang/Frontend/PCHReader.h
+++ b/include/clang/Frontend/PCHReader.h
@@ -379,6 +379,9 @@
/// \brief The set of unused static functions stored in the the PCH
/// file.
llvm::SmallVector<uint64_t, 16> UnusedStaticFuncs;
+
+ /// \brief The set of weak undeclared identifiers stored in the the PCH file.
+ llvm::SmallVector<uint64_t, 64> WeakUndeclaredIdentifiers;
/// \brief The set of locally-scoped external declarations stored in
/// the the PCH file.
diff --git a/lib/Frontend/PCHReader.cpp b/lib/Frontend/PCHReader.cpp
index 2252fd4..7229775 100644
--- a/lib/Frontend/PCHReader.cpp
+++ b/lib/Frontend/PCHReader.cpp
@@ -1642,6 +1642,15 @@
Record.begin(), Record.end());
break;
+ case pch::WEAK_UNDECLARED_IDENTIFIERS:
+ // Optimization for the first block.
+ if (WeakUndeclaredIdentifiers.empty())
+ WeakUndeclaredIdentifiers.swap(Record);
+ else
+ WeakUndeclaredIdentifiers.insert(WeakUndeclaredIdentifiers.end(),
+ Record.begin(), Record.end());
+ break;
+
case pch::LOCALLY_SCOPED_EXTERNAL_DECLS:
// Optimization for the first block.
if (LocallyScopedExternalDecls.empty())
@@ -3131,6 +3140,21 @@
SemaObj->UnusedStaticFuncs.push_back(FD);
}
+ // If there were any weak undeclared identifiers, deserialize them and add to
+ // Sema's list of weak undeclared identifiers.
+ if (!WeakUndeclaredIdentifiers.empty()) {
+ unsigned Idx = 0;
+ for (unsigned I = 0, N = WeakUndeclaredIdentifiers[Idx++]; I != N; ++I) {
+ IdentifierInfo *WeakId = GetIdentifierInfo(WeakUndeclaredIdentifiers,Idx);
+ IdentifierInfo *AliasId=GetIdentifierInfo(WeakUndeclaredIdentifiers,Idx);
+ SourceLocation Loc = ReadSourceLocation(WeakUndeclaredIdentifiers, Idx);
+ bool Used = WeakUndeclaredIdentifiers[Idx++];
+ Sema::WeakInfo WI(AliasId, Loc);
+ WI.setUsed(Used);
+ SemaObj->WeakUndeclaredIdentifiers.insert(std::make_pair(WeakId, WI));
+ }
+ }
+
// If there were any locally-scoped external declarations,
// deserialize them and add them to Sema's table of locally-scoped
// external declarations.
diff --git a/lib/Frontend/PCHWriter.cpp b/lib/Frontend/PCHWriter.cpp
index b2fd984..d6dc36f 100644
--- a/lib/Frontend/PCHWriter.cpp
+++ b/lib/Frontend/PCHWriter.cpp
@@ -2207,6 +2207,20 @@
RecordData UnusedStaticFuncs;
for (unsigned i=0, e = SemaRef.UnusedStaticFuncs.size(); i !=e; ++i)
AddDeclRef(SemaRef.UnusedStaticFuncs[i], UnusedStaticFuncs);
+
+ RecordData WeakUndeclaredIdentifiers;
+ if (!SemaRef.WeakUndeclaredIdentifiers.empty()) {
+ WeakUndeclaredIdentifiers.push_back(
+ SemaRef.WeakUndeclaredIdentifiers.size());
+ for (llvm::DenseMap<IdentifierInfo*,Sema::WeakInfo>::iterator
+ I = SemaRef.WeakUndeclaredIdentifiers.begin(),
+ E = SemaRef.WeakUndeclaredIdentifiers.end(); I != E; ++I) {
+ AddIdentifierRef(I->first, WeakUndeclaredIdentifiers);
+ AddIdentifierRef(I->second.getAlias(), WeakUndeclaredIdentifiers);
+ AddSourceLocation(I->second.getLocation(), WeakUndeclaredIdentifiers);
+ WeakUndeclaredIdentifiers.push_back(I->second.getUsed());
+ }
+ }
// Build a record containing all of the locally-scoped external
// declarations in this header file. Generally, this record will be
@@ -2311,6 +2325,11 @@
if (!UnusedStaticFuncs.empty())
Stream.EmitRecord(pch::UNUSED_STATIC_FUNCS, UnusedStaticFuncs);
+ // Write the record containing weak undeclared identifiers.
+ if (!WeakUndeclaredIdentifiers.empty())
+ Stream.EmitRecord(pch::WEAK_UNDECLARED_IDENTIFIERS,
+ WeakUndeclaredIdentifiers);
+
// Write the record containing locally-scoped external definitions.
if (!LocallyScopedExternalDecls.empty())
Stream.EmitRecord(pch::LOCALLY_SCOPED_EXTERNAL_DECLS,
diff --git a/lib/Sema/Sema.cpp b/lib/Sema/Sema.cpp
index 2c834f4..6de4202 100644
--- a/lib/Sema/Sema.cpp
+++ b/lib/Sema/Sema.cpp
@@ -243,6 +243,9 @@
true)),
UnusedStaticFuncs.end());
+ if (!CompleteTranslationUnit)
+ return;
+
// Check for #pragma weak identifiers that were never declared
// FIXME: This will cause diagnostics to be emitted in a non-determinstic
// order! Iterating over a densemap like this is bad.
@@ -255,9 +258,6 @@
<< I->first;
}
- if (!CompleteTranslationUnit)
- return;
-
// C99 6.9.2p2:
// A declaration of an identifier for an object that has file
// scope without an initializer, and without a storage-class
diff --git a/test/PCH/pragma-weak.c b/test/PCH/pragma-weak.c
new file mode 100644
index 0000000..18b45c8
--- /dev/null
+++ b/test/PCH/pragma-weak.c
@@ -0,0 +1,10 @@
+// Test this without pch.
+// RUN: %clang_cc1 -include %S/pragma-weak.h %s -verify -emit-llvm -o - | FileCheck %s
+
+// Test with pch.
+// RUN: %clang_cc1 -x c-header -emit-pch -o %t %S/pragma-weak.h
+// RUN: %clang_cc1 -include-pch %t %s -verify -emit-llvm -o - | FileCheck %s
+
+// CHECK: @weakvar = weak global i32 0
+int weakvar;
+// expected-warning {{weak identifier 'undeclaredvar' never declared}}
diff --git a/test/PCH/pragma-weak.h b/test/PCH/pragma-weak.h
new file mode 100644
index 0000000..42ecd50
--- /dev/null
+++ b/test/PCH/pragma-weak.h
@@ -0,0 +1,10 @@
+// Header for PCH test pragma-weak.c
+
+#pragma weak weakvar
+
+
+
+
+
+
+#pragma weak undeclaredvar