#define LLVM_CLANG_SEMA_EXTERNAL_SEMA_SOURCE_H
#include "clang/AST/ExternalASTSource.h"
+#include "clang/Sema/Weak.h"
#include <utility>
namespace clang {
/// 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;
#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"
/// 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
--- /dev/null
+//===-- 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
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);
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);
}
}
+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.
// 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) {
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;
+ }
}
}
}
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:
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()) {
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);
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);
// 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);