forked from OSchip/llvm-project
Preserve Sema::UndefinedInternals across PCH boundaries. Fixes
-Wundefined-internal warnings with PCH. llvm-svn: 173538
This commit is contained in:
parent
9a8ff813f3
commit
8334af8c2a
|
@ -15,6 +15,7 @@
|
|||
|
||||
#include "clang/AST/ExternalASTSource.h"
|
||||
#include "clang/Sema/Weak.h"
|
||||
#include "llvm/ADT/MapVector.h"
|
||||
#include <utility>
|
||||
|
||||
namespace clang {
|
||||
|
@ -65,6 +66,9 @@ public:
|
|||
/// which will be used during typo correction.
|
||||
virtual void ReadKnownNamespaces(
|
||||
SmallVectorImpl<NamespaceDecl *> &Namespaces);
|
||||
|
||||
virtual void ReadUndefinedInternals(
|
||||
llvm::MapVector<NamedDecl*, SourceLocation> &Undefined);
|
||||
|
||||
/// \brief Do last resort, unqualified lookup on a LookupResult that
|
||||
/// Sema cannot find.
|
||||
|
|
|
@ -252,6 +252,9 @@ public:
|
|||
/// \brief Load the set of namespaces that are known to the external source,
|
||||
/// which will be used during typo correction.
|
||||
virtual void ReadKnownNamespaces(SmallVectorImpl<NamespaceDecl*> &Namespaces);
|
||||
|
||||
virtual void ReadUndefinedInternals(
|
||||
llvm::MapVector<NamedDecl*, SourceLocation> &Undefined);
|
||||
|
||||
/// \brief Do last resort, unqualified lookup on a LookupResult that
|
||||
/// Sema cannot find.
|
||||
|
|
|
@ -740,7 +740,7 @@ public:
|
|||
|
||||
/// UndefinedInternals - all the used, undefined objects with
|
||||
/// internal linkage in this translation unit.
|
||||
llvm::DenseMap<NamedDecl*, SourceLocation> UndefinedInternals;
|
||||
llvm::MapVector<NamedDecl*, SourceLocation> UndefinedInternals;
|
||||
|
||||
typedef std::pair<ObjCMethodList, ObjCMethodList> GlobalMethods;
|
||||
typedef llvm::DenseMap<Selector, GlobalMethods> GlobalMethodPool;
|
||||
|
@ -2234,7 +2234,7 @@ private:
|
|||
//
|
||||
// The boolean value will be true to indicate that the namespace was loaded
|
||||
// from an AST/PCH file, or false otherwise.
|
||||
llvm::DenseMap<NamespaceDecl*, bool> KnownNamespaces;
|
||||
llvm::MapVector<NamespaceDecl*, bool> KnownNamespaces;
|
||||
|
||||
/// \brief Whether we have already loaded known namespaces from an extenal
|
||||
/// source.
|
||||
|
|
|
@ -524,7 +524,11 @@ namespace clang {
|
|||
|
||||
/// \brief Record of updates for a macro that was modified after
|
||||
/// being deserialized.
|
||||
MACRO_UPDATES = 48
|
||||
MACRO_UPDATES = 48,
|
||||
|
||||
/// \brief Record code for undefined but used internal functions and
|
||||
/// variables.
|
||||
UNDEFINED_INTERNALS = 49
|
||||
};
|
||||
|
||||
/// \brief Record types used within a source manager block.
|
||||
|
|
|
@ -677,6 +677,9 @@ private:
|
|||
/// \brief A list of the namespaces we've seen.
|
||||
SmallVector<uint64_t, 4> KnownNamespaces;
|
||||
|
||||
/// \brief A list of undefined decls with internal linkage.
|
||||
SmallVector<uint64_t, 8> UndefinedInternals;
|
||||
|
||||
/// \brief A list of modules that were imported by precompiled headers or
|
||||
/// any other non-module AST file.
|
||||
SmallVector<serialization::SubmoduleID, 2> ImportedModules;
|
||||
|
@ -1505,6 +1508,9 @@ public:
|
|||
virtual void ReadKnownNamespaces(
|
||||
SmallVectorImpl<NamespaceDecl *> &Namespaces);
|
||||
|
||||
virtual void ReadUndefinedInternals(
|
||||
llvm::MapVector<NamedDecl *, SourceLocation> &Undefined);
|
||||
|
||||
virtual void ReadTentativeDefinitions(
|
||||
SmallVectorImpl<VarDecl *> &TentativeDefs);
|
||||
|
||||
|
@ -1675,13 +1681,13 @@ public:
|
|||
|
||||
/// \brief Read a source location.
|
||||
SourceLocation ReadSourceLocation(ModuleFile &ModuleFile,
|
||||
const RecordData &Record, unsigned& Idx) {
|
||||
const RecordData &Record, unsigned &Idx) {
|
||||
return ReadSourceLocation(ModuleFile, Record[Idx++]);
|
||||
}
|
||||
|
||||
/// \brief Read a source range.
|
||||
SourceRange ReadSourceRange(ModuleFile &F,
|
||||
const RecordData &Record, unsigned& Idx);
|
||||
const RecordData &Record, unsigned &Idx);
|
||||
|
||||
/// \brief Read an integral value
|
||||
llvm::APInt ReadAPInt(const RecordData &Record, unsigned &Idx);
|
||||
|
|
|
@ -200,6 +200,12 @@ void MultiplexExternalSemaSource::ReadKnownNamespaces(
|
|||
for(size_t i = 0; i < Sources.size(); ++i)
|
||||
Sources[i]->ReadKnownNamespaces(Namespaces);
|
||||
}
|
||||
|
||||
void MultiplexExternalSemaSource::ReadUndefinedInternals(
|
||||
llvm::MapVector<NamedDecl*, SourceLocation> &Undefined){
|
||||
for(size_t i = 0; i < Sources.size(); ++i)
|
||||
Sources[i]->ReadUndefinedInternals(Undefined);
|
||||
}
|
||||
|
||||
bool MultiplexExternalSemaSource::LookupUnqualified(LookupResult &R, Scope *S){
|
||||
for(size_t i = 0; i < Sources.size(); ++i)
|
||||
|
|
|
@ -385,7 +385,7 @@ static void checkUndefinedInternals(Sema &S) {
|
|||
|
||||
// Collect all the still-undefined entities with internal linkage.
|
||||
SmallVector<UndefinedInternal, 16> undefined;
|
||||
for (llvm::DenseMap<NamedDecl*,SourceLocation>::iterator
|
||||
for (llvm::MapVector<NamedDecl*,SourceLocation>::iterator
|
||||
i = S.UndefinedInternals.begin(), e = S.UndefinedInternals.end();
|
||||
i != e; ++i) {
|
||||
NamedDecl *decl = i->first;
|
||||
|
@ -407,23 +407,9 @@ static void checkUndefinedInternals(Sema &S) {
|
|||
continue;
|
||||
}
|
||||
|
||||
// We build a FullSourceLoc so that we can sort with array_pod_sort.
|
||||
FullSourceLoc loc(i->second, S.Context.getSourceManager());
|
||||
undefined.push_back(UndefinedInternal(decl, loc));
|
||||
}
|
||||
|
||||
if (undefined.empty()) return;
|
||||
|
||||
// Sort (in order of use site) so that we're not (as) dependent on
|
||||
// the iteration order through an llvm::DenseMap.
|
||||
llvm::array_pod_sort(undefined.begin(), undefined.end());
|
||||
|
||||
for (SmallVectorImpl<UndefinedInternal>::iterator
|
||||
i = undefined.begin(), e = undefined.end(); i != e; ++i) {
|
||||
NamedDecl *decl = i->decl;
|
||||
S.Diag(decl->getLocation(), diag::warn_undefined_internal)
|
||||
<< isa<VarDecl>(decl) << decl;
|
||||
S.Diag(i->useLoc, diag::note_used_here);
|
||||
S.Diag(i->second, diag::note_used_here);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -736,6 +722,8 @@ void Sema::ActOnEndOfTranslationUnit() {
|
|||
}
|
||||
}
|
||||
|
||||
if (ExternalSource)
|
||||
ExternalSource->ReadUndefinedInternals(UndefinedInternals);
|
||||
checkUndefinedInternals(*this);
|
||||
}
|
||||
|
||||
|
@ -1080,6 +1068,10 @@ void ExternalSemaSource::ReadKnownNamespaces(
|
|||
SmallVectorImpl<NamespaceDecl *> &Namespaces) {
|
||||
}
|
||||
|
||||
void ExternalSemaSource::ReadUndefinedInternals(
|
||||
llvm::MapVector<NamedDecl *, SourceLocation> &Undefined) {
|
||||
}
|
||||
|
||||
void PrettyDeclStackTraceEntry::print(raw_ostream &OS) const {
|
||||
SourceLocation Loc = this->Loc;
|
||||
if (!Loc.isValid() && TheDecl) Loc = TheDecl->getLocation();
|
||||
|
|
|
@ -3857,7 +3857,7 @@ TypoCorrection Sema::CorrectTypo(const DeclarationNameInfo &TypoName,
|
|||
KnownNamespaces[ExternalKnownNamespaces[I]] = true;
|
||||
}
|
||||
|
||||
for (llvm::DenseMap<NamespaceDecl*, bool>::iterator
|
||||
for (llvm::MapVector<NamespaceDecl*, bool>::iterator
|
||||
KNI = KnownNamespaces.begin(),
|
||||
KNIEnd = KnownNamespaces.end();
|
||||
KNI != KNIEnd; ++KNI)
|
||||
|
|
|
@ -2461,7 +2461,24 @@ bool ASTReader::ReadASTBlock(ModuleFile &F) {
|
|||
for (unsigned I = 0, N = Record.size(); I != N; ++I)
|
||||
KnownNamespaces.push_back(getGlobalDeclID(F, Record[I]));
|
||||
break;
|
||||
|
||||
|
||||
case UNDEFINED_INTERNALS:
|
||||
if (UndefinedInternals.size() % 2 != 0) {
|
||||
Error("Invalid existing UndefinedInternals");
|
||||
return true;
|
||||
}
|
||||
|
||||
if (Record.size() % 2 != 0) {
|
||||
Error("invalid undefined internals record");
|
||||
return true;
|
||||
}
|
||||
for (unsigned I = 0, N = Record.size(); I != N; /* in loop */) {
|
||||
UndefinedInternals.push_back(getGlobalDeclID(F, Record[I++]));
|
||||
UndefinedInternals.push_back(
|
||||
ReadSourceLocation(F, Record, I).getRawEncoding());
|
||||
}
|
||||
break;
|
||||
|
||||
case IMPORTED_MODULES: {
|
||||
if (F.Kind != MK_Module) {
|
||||
// If we aren't loading a module (which has its own exports), make
|
||||
|
@ -5934,6 +5951,17 @@ void ASTReader::ReadKnownNamespaces(
|
|||
}
|
||||
}
|
||||
|
||||
void ASTReader::ReadUndefinedInternals(
|
||||
llvm::MapVector<NamedDecl*, SourceLocation> &Undefined) {
|
||||
for (unsigned Idx = 0, N = UndefinedInternals.size(); Idx != N;) {
|
||||
NamedDecl *D = cast<NamedDecl>(GetDecl(UndefinedInternals[Idx++]));
|
||||
SourceLocation Loc =
|
||||
SourceLocation::getFromRawEncoding(UndefinedInternals[Idx++]);
|
||||
Undefined.insert(std::make_pair(D, Loc));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void ASTReader::ReadTentativeDefinitions(
|
||||
SmallVectorImpl<VarDecl *> &TentativeDefs) {
|
||||
for (unsigned I = 0, N = TentativeDefinitions.size(); I != N; ++I) {
|
||||
|
|
|
@ -824,6 +824,7 @@ void ASTWriter::WriteBlockInfoBlock() {
|
|||
RECORD(OPENCL_EXTENSIONS);
|
||||
RECORD(DELEGATING_CTORS);
|
||||
RECORD(KNOWN_NAMESPACES);
|
||||
RECORD(UNDEFINED_INTERNALS);
|
||||
RECORD(MODULE_OFFSET_MAP);
|
||||
RECORD(SOURCE_MANAGER_LINE_TABLE);
|
||||
RECORD(OBJC_CATEGORIES_MAP);
|
||||
|
@ -3581,7 +3582,7 @@ void ASTWriter::WriteASTCore(Sema &SemaRef,
|
|||
|
||||
// Build a record containing all of the known namespaces.
|
||||
RecordData KnownNamespaces;
|
||||
for (llvm::DenseMap<NamespaceDecl*, bool>::iterator
|
||||
for (llvm::MapVector<NamespaceDecl*, bool>::iterator
|
||||
I = SemaRef.KnownNamespaces.begin(),
|
||||
IEnd = SemaRef.KnownNamespaces.end();
|
||||
I != IEnd; ++I) {
|
||||
|
@ -3589,6 +3590,16 @@ void ASTWriter::WriteASTCore(Sema &SemaRef,
|
|||
AddDeclRef(I->first, KnownNamespaces);
|
||||
}
|
||||
|
||||
// Build a record of all used, undefined objects with internal linkage.
|
||||
RecordData UndefinedInternals;
|
||||
for (llvm::MapVector<NamedDecl*, SourceLocation>::iterator
|
||||
I = SemaRef.UndefinedInternals.begin(),
|
||||
IEnd = SemaRef.UndefinedInternals.end();
|
||||
I != IEnd; ++I) {
|
||||
AddDeclRef(I->first, UndefinedInternals);
|
||||
AddSourceLocation(I->second, UndefinedInternals);
|
||||
}
|
||||
|
||||
// Write the control block
|
||||
WriteControlBlock(PP, Context, isysroot, OutputFile);
|
||||
|
||||
|
@ -3803,6 +3814,10 @@ void ASTWriter::WriteASTCore(Sema &SemaRef,
|
|||
// Write the known namespaces.
|
||||
if (!KnownNamespaces.empty())
|
||||
Stream.EmitRecord(KNOWN_NAMESPACES, KnownNamespaces);
|
||||
|
||||
// Write the undefined internal functions and variables.
|
||||
if (!UndefinedInternals.empty())
|
||||
Stream.EmitRecord(UNDEFINED_INTERNALS, UndefinedInternals);
|
||||
|
||||
// Write the visible updates to DeclContexts.
|
||||
for (llvm::SmallPtrSet<const DeclContext *, 16>::iterator
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
// RUN: %clang_cc1 -emit-pch %s -o %t
|
||||
// RUN: %clang_cc1 -include-pch %t %s -verify
|
||||
#ifndef HEADER_H
|
||||
#define HEADER_H
|
||||
static void f();
|
||||
static void g();
|
||||
void h() {
|
||||
f();
|
||||
g();
|
||||
}
|
||||
#else
|
||||
static void g() {}
|
||||
// expected-warning@5{{function 'f' has internal linkage but is not defined}}
|
||||
// expected-note@8{{used here}}
|
||||
#endif
|
Loading…
Reference in New Issue