diff options
-rw-r--r-- | include/clang/Sema/ExternalSemaSource.h | 13 | ||||
-rw-r--r-- | include/clang/Sema/Sema.h | 22 | ||||
-rw-r--r-- | include/clang/Sema/Weak.h | 46 | ||||
-rw-r--r-- | include/clang/Serialization/ASTReader.h | 8 | ||||
-rw-r--r-- | lib/Sema/Sema.cpp | 17 | ||||
-rw-r--r-- | lib/Sema/SemaDeclAttr.cpp | 21 | ||||
-rw-r--r-- | lib/Serialization/ASTReader.cpp | 56 | ||||
-rw-r--r-- | lib/Serialization/ASTWriter.cpp | 8 |
8 files changed, 140 insertions, 51 deletions
diff --git a/include/clang/Sema/ExternalSemaSource.h b/include/clang/Sema/ExternalSemaSource.h index d8d6abb650..41bc4e3536 100644 --- a/include/clang/Sema/ExternalSemaSource.h +++ b/include/clang/Sema/ExternalSemaSource.h @@ -14,6 +14,7 @@ #define LLVM_CLANG_SEMA_EXTERNAL_SEMA_SOURCE_H #include "clang/AST/ExternalASTSource.h" +#include "clang/Sema/Weak.h" #include <utility> namespace clang { @@ -130,12 +131,22 @@ public: /// external Sema source. /// /// The external source should append its own referenced selectors to the - /// given vector of declarations. Note that this routine + /// given vector of selectors. Note that this routine /// may be invoked multiple times; the external source should take care not /// to introduce the same selectors repeatedly. virtual void ReadReferencedSelectors( SmallVectorImpl<std::pair<Selector, SourceLocation> > &Sels) {} + /// \brief Read the set of weak, undeclared identifiers known to the + /// external Sema source. + /// + /// The external source should append its own weak, undeclared identifiers to + /// the given vector. Note that this routine may be invoked multiple times; + /// the external source should take care not to introduce the same identifiers + /// repeatedly. + virtual void ReadWeakUndeclaredIdentifiers( + SmallVectorImpl<std::pair<IdentifierInfo *, WeakInfo> > &WI) {} + // isa/cast/dyn_cast support static bool classof(const ExternalASTSource *Source) { return Source->SemaSource; diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h index c68852b20a..adc6e2ba6d 100644 --- a/include/clang/Sema/Sema.h +++ b/include/clang/Sema/Sema.h @@ -23,6 +23,7 @@ #include "clang/Sema/ExternalSemaSource.h" #include "clang/Sema/LocInfoType.h" #include "clang/Sema/TypoCorrection.h" +#include "clang/Sema/Weak.h" #include "clang/AST/Expr.h" #include "clang/AST/DeclarationName.h" #include "clang/AST/ExternalASTSource.h" @@ -452,26 +453,11 @@ public: /// WeakUndeclaredIdentifiers - Identifiers contained in /// #pragma weak before declared. rare. may alias another /// identifier, declared or undeclared - class WeakInfo { - IdentifierInfo *alias; // alias (optional) - SourceLocation loc; // for diagnostics - bool used; // identifier later declared? - public: - WeakInfo() - : alias(0), loc(SourceLocation()), used(false) {} - WeakInfo(IdentifierInfo *Alias, SourceLocation Loc) - : alias(Alias), loc(Loc), used(false) {} - inline IdentifierInfo * getAlias() const { return alias; } - inline SourceLocation getLocation() const { return loc; } - void setUsed(bool Used=true) { used = Used; } - inline bool getUsed() { return used; } - bool operator==(WeakInfo RHS) const { - return alias == RHS.getAlias() && loc == RHS.getLocation(); - } - bool operator!=(WeakInfo RHS) const { return !(*this == RHS); } - }; llvm::DenseMap<IdentifierInfo*,WeakInfo> WeakUndeclaredIdentifiers; + /// \brief Load weak undeclared identifiers from the external source. + void LoadExternalWeakUndeclaredIdentifiers(); + /// WeakTopLevelDecl - Translation-unit scoped declarations generated by /// #pragma weak during processing of other Decls. /// I couldn't figure out a clean way to generate these in-line, so diff --git a/include/clang/Sema/Weak.h b/include/clang/Sema/Weak.h new file mode 100644 index 0000000000..d36b970893 --- /dev/null +++ b/include/clang/Sema/Weak.h @@ -0,0 +1,46 @@ +//===-- UnresolvedSet.h - Unresolved sets of declarations ------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines the WeakInfo class, which is used to store +// information about the target of a #pragma weak directive. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_SEMA_WEAK_H +#define LLVM_CLANG_SEMA_WEAK_H + +#include "clang/Basic/SourceLocation.h" + +namespace clang { + +class IdentifierInfo; + +/// \brief Captures information about a #pragma weak directive. +class WeakInfo { + IdentifierInfo *alias; // alias (optional) + SourceLocation loc; // for diagnostics + bool used; // identifier later declared? +public: + WeakInfo() + : alias(0), loc(SourceLocation()), used(false) {} + WeakInfo(IdentifierInfo *Alias, SourceLocation Loc) + : alias(Alias), loc(Loc), used(false) {} + inline IdentifierInfo * getAlias() const { return alias; } + inline SourceLocation getLocation() const { return loc; } + void setUsed(bool Used=true) { used = Used; } + inline bool getUsed() { return used; } + bool operator==(WeakInfo RHS) const { + return alias == RHS.getAlias() && loc == RHS.getLocation(); + } + bool operator!=(WeakInfo RHS) const { return !(*this == RHS); } +}; + +} // end namespace clang + +#endif // LLVM_CLANG_SEMA_WEAK_H diff --git a/include/clang/Serialization/ASTReader.h b/include/clang/Serialization/ASTReader.h index 59a4fdceb2..8bb11cc575 100644 --- a/include/clang/Serialization/ASTReader.h +++ b/include/clang/Serialization/ASTReader.h @@ -1401,6 +1401,9 @@ public: virtual void ReadReferencedSelectors( SmallVectorImpl<std::pair<Selector, SourceLocation> > &Sels); + virtual void ReadWeakUndeclaredIdentifiers( + SmallVectorImpl<std::pair<IdentifierInfo *, WeakInfo> > &WI); + /// \brief Load a selector from disk, registering its ID if it exists. void LoadSelector(Selector Sel); @@ -1425,6 +1428,11 @@ public: return DecodeIdentifierInfo(ID); } + unsigned getGlobalIdentifierID(Module &M, unsigned LocalID) { + // FIXME: Remap local -> global identifier IDs + return LocalID; + } + /// \brief Read the source location entry with index ID. virtual bool ReadSLocEntry(int ID); diff --git a/lib/Sema/Sema.cpp b/lib/Sema/Sema.cpp index e598956eeb..fb6049b18e 100644 --- a/lib/Sema/Sema.cpp +++ b/lib/Sema/Sema.cpp @@ -398,6 +398,22 @@ static void checkUndefinedInternals(Sema &S) { } } +void Sema::LoadExternalWeakUndeclaredIdentifiers() { + if (!ExternalSource) + return; + + SmallVector<std::pair<IdentifierInfo *, WeakInfo>, 4> WeakIDs; + ExternalSource->ReadWeakUndeclaredIdentifiers(WeakIDs); + for (unsigned I = 0, N = WeakIDs.size(); I != N; ++I) { + llvm::DenseMap<IdentifierInfo*,WeakInfo>::iterator Pos + = WeakUndeclaredIdentifiers.find(WeakIDs[I].first); + if (Pos != WeakUndeclaredIdentifiers.end()) + continue; + + WeakUndeclaredIdentifiers.insert(WeakIDs[I]); + } +} + /// ActOnEndOfTranslationUnit - This is called at the very end of the /// translation unit when EOF is reached and all but the top-level scope is /// popped. @@ -454,6 +470,7 @@ void Sema::ActOnEndOfTranslationUnit() { // 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. + LoadExternalWeakUndeclaredIdentifiers(); for (llvm::DenseMap<IdentifierInfo*,WeakInfo>::iterator I = WeakUndeclaredIdentifiers.begin(), E = WeakUndeclaredIdentifiers.end(); I != E; ++I) { diff --git a/lib/Sema/SemaDeclAttr.cpp b/lib/Sema/SemaDeclAttr.cpp index 2294c0e784..694d38b4a1 100644 --- a/lib/Sema/SemaDeclAttr.cpp +++ b/lib/Sema/SemaDeclAttr.cpp @@ -3289,15 +3289,18 @@ void Sema::ProcessDeclAttributes(Scope *S, Decl *D, const Declarator &PD, bool NonInheritable, bool Inheritable) { // It's valid to "forward-declare" #pragma weak, in which case we // have to do this. - if (Inheritable && !WeakUndeclaredIdentifiers.empty()) { - if (NamedDecl *ND = dyn_cast<NamedDecl>(D)) { - if (IdentifierInfo *Id = ND->getIdentifier()) { - llvm::DenseMap<IdentifierInfo*,WeakInfo>::iterator I - = WeakUndeclaredIdentifiers.find(Id); - if (I != WeakUndeclaredIdentifiers.end() && ND->hasLinkage()) { - WeakInfo W = I->second; - DeclApplyPragmaWeak(S, ND, W); - WeakUndeclaredIdentifiers[Id] = W; + if (Inheritable) { + LoadExternalWeakUndeclaredIdentifiers(); + if (!WeakUndeclaredIdentifiers.empty()) { + if (NamedDecl *ND = dyn_cast<NamedDecl>(D)) { + if (IdentifierInfo *Id = ND->getIdentifier()) { + llvm::DenseMap<IdentifierInfo*,WeakInfo>::iterator I + = WeakUndeclaredIdentifiers.find(Id); + if (I != WeakUndeclaredIdentifiers.end() && ND->hasLinkage()) { + WeakInfo W = I->second; + DeclApplyPragmaWeak(S, ND, W); + WeakUndeclaredIdentifiers[Id] = W; + } } } } diff --git a/lib/Serialization/ASTReader.cpp b/lib/Serialization/ASTReader.cpp index 8e214a3bcf..ff87c23897 100644 --- a/lib/Serialization/ASTReader.cpp +++ b/lib/Serialization/ASTReader.cpp @@ -2162,8 +2162,25 @@ ASTReader::ReadASTBlock(Module &F) { break; case WEAK_UNDECLARED_IDENTIFIERS: - // Later blocks overwrite earlier ones. - WeakUndeclaredIdentifiers.swap(Record); + if (Record.size() % 4 != 0) { + Error("invalid weak identifiers record"); + return Failure; + } + + // FIXME: Ignore weak undeclared identifiers from non-original PCH + // files. This isn't the way to do it :) + WeakUndeclaredIdentifiers.clear(); + + // Translate the weak, undeclared identifiers into global IDs. + for (unsigned I = 0, N = Record.size(); I < N; /* in loop */) { + WeakUndeclaredIdentifiers.push_back( + getGlobalIdentifierID(F, Record[I++])); + WeakUndeclaredIdentifiers.push_back( + getGlobalIdentifierID(F, Record[I++])); + WeakUndeclaredIdentifiers.push_back( + ReadSourceLocation(F, Record, I).getRawEncoding()); + WeakUndeclaredIdentifiers.push_back(Record[I++]); + } break; case LOCALLY_SCOPED_EXTERNAL_DECLS: @@ -4380,21 +4397,6 @@ void ASTReader::InitializeSema(Sema &S) { SemaObj->PendingInstantiations.push_back(std::make_pair(D, Loc)); } - // 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(F, 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 VTable uses, deserialize the information and add it // to Sema's vector and map of VTable uses. if (!VTableUses.empty()) { @@ -4622,6 +4624,26 @@ void ASTReader::ReadReferencedSelectors( ReferencedSelectorsData.clear(); } +void ASTReader::ReadWeakUndeclaredIdentifiers( + SmallVectorImpl<std::pair<IdentifierInfo *, WeakInfo> > &WeakIDs) { + if (WeakUndeclaredIdentifiers.empty()) + return; + + for (unsigned I = 0, N = WeakUndeclaredIdentifiers.size(); I < N; /*none*/) { + IdentifierInfo *WeakId + = DecodeIdentifierInfo(WeakUndeclaredIdentifiers[I++]); + IdentifierInfo *AliasId + = DecodeIdentifierInfo(WeakUndeclaredIdentifiers[I++]); + SourceLocation Loc + = SourceLocation::getFromRawEncoding(WeakUndeclaredIdentifiers[I++]); + bool Used = WeakUndeclaredIdentifiers[I++]; + WeakInfo WI(AliasId, Loc); + WI.setUsed(Used); + WeakIDs.push_back(std::make_pair(WeakId, WI)); + } + WeakUndeclaredIdentifiers.clear(); +} + void ASTReader::LoadSelector(Selector Sel) { // It would be complicated to avoid reading the methods anyway. So don't. ReadMethodPool(Sel); diff --git a/lib/Serialization/ASTWriter.cpp b/lib/Serialization/ASTWriter.cpp index e63950e826..fb29f6970f 100644 --- a/lib/Serialization/ASTWriter.cpp +++ b/lib/Serialization/ASTWriter.cpp @@ -2855,9 +2855,7 @@ void ASTWriter::WriteASTCore(Sema &SemaRef, MemorizeStatCalls *StatCalls, RecordData WeakUndeclaredIdentifiers; if (!SemaRef.WeakUndeclaredIdentifiers.empty()) { - WeakUndeclaredIdentifiers.push_back( - SemaRef.WeakUndeclaredIdentifiers.size()); - for (llvm::DenseMap<IdentifierInfo*,Sema::WeakInfo>::iterator + for (llvm::DenseMap<IdentifierInfo*,WeakInfo>::iterator I = SemaRef.WeakUndeclaredIdentifiers.begin(), E = SemaRef.WeakUndeclaredIdentifiers.end(); I != E; ++I) { AddIdentifierRef(I->first, WeakUndeclaredIdentifiers); @@ -3122,9 +3120,7 @@ void ASTWriter::WriteASTChain(Sema &SemaRef, MemorizeStatCalls *StatCalls, // We write the entire table, overwriting the tables from the chain. RecordData WeakUndeclaredIdentifiers; if (!SemaRef.WeakUndeclaredIdentifiers.empty()) { - WeakUndeclaredIdentifiers.push_back( - SemaRef.WeakUndeclaredIdentifiers.size()); - for (llvm::DenseMap<IdentifierInfo*,Sema::WeakInfo>::iterator + for (llvm::DenseMap<IdentifierInfo*,WeakInfo>::iterator I = SemaRef.WeakUndeclaredIdentifiers.begin(), E = SemaRef.WeakUndeclaredIdentifiers.end(); I != E; ++I) { AddIdentifierRef(I->first, WeakUndeclaredIdentifiers); |