Support #pragma weak for PCH.

llvm-svn: 110323
This commit is contained in:
Argyrios Kyrtzidis 2010-08-05 09:48:08 +00:00
parent 4ba81b2ee4
commit ee1afa3082
7 changed files with 73 additions and 4 deletions

View File

@ -250,7 +250,10 @@ namespace clang {
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.

View File

@ -379,6 +379,9 @@ private:
/// \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.

View File

@ -1642,6 +1642,15 @@ PCHReader::ReadPCHBlock(PerFileData &F) {
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 @@ void PCHReader::InitializeSema(Sema &S) {
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.

View File

@ -2207,6 +2207,20 @@ void PCHWriter::WritePCHCore(Sema &SemaRef, MemorizeStatCalls *StatCalls,
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 @@ void PCHWriter::WritePCHCore(Sema &SemaRef, MemorizeStatCalls *StatCalls,
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,

View File

@ -243,6 +243,9 @@ void Sema::ActOnEndOfTranslationUnit() {
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 @@ void Sema::ActOnEndOfTranslationUnit() {
<< 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

View File

@ -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}}

View File

@ -0,0 +1,10 @@
// Header for PCH test pragma-weak.c
#pragma weak weakvar
#pragma weak undeclaredvar