From 72b90571b1783b17c3f2204cec5ca440edc38bee Mon Sep 17 00:00:00 2001 From: Argyrios Kyrtzidis Date: Thu, 5 Aug 2010 09:48:08 +0000 Subject: [PATCH] Support #pragma weak for PCH. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@110323 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/Frontend/PCHBitCodes.h | 5 ++++- include/clang/Frontend/PCHReader.h | 3 +++ lib/Frontend/PCHReader.cpp | 24 ++++++++++++++++++++++++ lib/Frontend/PCHWriter.cpp | 19 +++++++++++++++++++ lib/Sema/Sema.cpp | 6 +++--- test/PCH/pragma-weak.c | 10 ++++++++++ test/PCH/pragma-weak.h | 10 ++++++++++ 7 files changed, 73 insertions(+), 4 deletions(-) create mode 100644 test/PCH/pragma-weak.c create mode 100644 test/PCH/pragma-weak.h diff --git a/include/clang/Frontend/PCHBitCodes.h b/include/clang/Frontend/PCHBitCodes.h index a07060f800..37337963a1 100644 --- a/include/clang/Frontend/PCHBitCodes.h +++ b/include/clang/Frontend/PCHBitCodes.h @@ -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. diff --git a/include/clang/Frontend/PCHReader.h b/include/clang/Frontend/PCHReader.h index f7690fbb21..76975a0e01 100644 --- a/include/clang/Frontend/PCHReader.h +++ b/include/clang/Frontend/PCHReader.h @@ -379,6 +379,9 @@ private: /// \brief The set of unused static functions stored in the the PCH /// file. llvm::SmallVector UnusedStaticFuncs; + + /// \brief The set of weak undeclared identifiers stored in the the PCH file. + llvm::SmallVector 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 2252fd4729..7229775070 100644 --- a/lib/Frontend/PCHReader.cpp +++ b/lib/Frontend/PCHReader.cpp @@ -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. diff --git a/lib/Frontend/PCHWriter.cpp b/lib/Frontend/PCHWriter.cpp index b2fd984766..d6dc36fd30 100644 --- a/lib/Frontend/PCHWriter.cpp +++ b/lib/Frontend/PCHWriter.cpp @@ -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::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, diff --git a/lib/Sema/Sema.cpp b/lib/Sema/Sema.cpp index 2c834f4349..6de4202bae 100644 --- a/lib/Sema/Sema.cpp +++ b/lib/Sema/Sema.cpp @@ -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 diff --git a/test/PCH/pragma-weak.c b/test/PCH/pragma-weak.c new file mode 100644 index 0000000000..18b45c889d --- /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 0000000000..42ecd50b9f --- /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 -- 2.40.0