update the identifier in case we've imported a definition of the macro (and
thus the contents of the header) from a module.
Also fold ExternalIdentifierLookup into ExternalPreprocessorSource; it no longer
makes sense to keep these separate now that the only user of the former also
needs the latter.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@241137
91177308-0d34-0410-b5e6-
96231b3b80d8
virtual IdentifierIterator *getIdentifiers();
};
-/// \brief An abstract class used to resolve numerical identifier
-/// references (meaningful only to some external source) into
-/// IdentifierInfo pointers.
-class ExternalIdentifierLookup {
-public:
- virtual ~ExternalIdentifierLookup();
-
- /// \brief Return the identifier associated with the given ID number.
- ///
- /// The ID 0 is associated with the NULL identifier.
- virtual IdentifierInfo *GetIdentifier(unsigned ID) = 0;
-};
-
/// \brief Implements an efficient mapping from strings to IdentifierInfo nodes.
///
/// This has no other purpose, but this is an extremely performance-critical
/// information.
///
/// This abstract class allows an external sources (such as the \c ASTReader)
-/// to provide additional macro definitions.
+/// to provide additional preprocessing information.
class ExternalPreprocessorSource {
public:
virtual ~ExternalPreprocessorSource();
/// \brief Update an out-of-date identifier.
virtual void updateOutOfDateIdentifier(IdentifierInfo &II) = 0;
+ /// \brief Return the identifier associated with the given ID number.
+ ///
+ /// The ID 0 is associated with the NULL identifier.
+ virtual IdentifierInfo *GetIdentifier(unsigned ID) = 0;
+
/// \brief Map a module ID to a module.
virtual Module *getModule(unsigned ModuleID) = 0;
};
namespace clang {
class DiagnosticsEngine;
-class ExternalIdentifierLookup;
+class ExternalPreprocessorSource;
class FileEntry;
class FileManager;
class HeaderSearchOptions;
/// \brief Retrieve the controlling macro for this header file, if
/// any.
- const IdentifierInfo *getControllingMacro(ExternalIdentifierLookup *External);
-
+ const IdentifierInfo *
+ getControllingMacro(ExternalPreprocessorSource *External);
+
/// \brief Determine whether this is a non-default header file info, e.g.,
/// it corresponds to an actual header we've included or tried to include.
bool isNonDefault() const {
llvm::StringSet<llvm::BumpPtrAllocator> FrameworkNames;
/// \brief Entity used to resolve the identifier IDs of controlling
- /// macros into IdentifierInfo pointers, as needed.
- ExternalIdentifierLookup *ExternalLookup;
+ /// macros into IdentifierInfo pointers, and keep the identifire up to date,
+ /// as needed.
+ ExternalPreprocessorSource *ExternalLookup;
/// \brief Entity used to look up stored header file information.
ExternalHeaderFileInfoSource *ExternalSource;
FileInfo.clear();
}
- void SetExternalLookup(ExternalIdentifierLookup *EIL) {
- ExternalLookup = EIL;
+ void SetExternalLookup(ExternalPreprocessorSource *EPS) {
+ ExternalLookup = EPS;
}
- ExternalIdentifierLookup *getExternalLookup() const {
+ ExternalPreprocessorSource *getExternalLookup() const {
return ExternalLookup;
}
public ExternalHeaderFileInfoSource,
public ExternalSemaSource,
public IdentifierInfoLookup,
- public ExternalIdentifierLookup,
public ExternalSLocEntrySource
{
public:
return new EmptyLookupIterator();
}
-ExternalIdentifierLookup::~ExternalIdentifierLookup() {}
-
IdentifierTable::IdentifierTable(const LangOptions &LangOpts,
IdentifierInfoLookup* externalLookup)
: HashTable(8192), // Start with space for 8K identifiers.
#include "clang/Lex/HeaderSearch.h"
#include "clang/Basic/FileManager.h"
#include "clang/Basic/IdentifierTable.h"
+#include "clang/Lex/ExternalPreprocessorSource.h"
#include "clang/Lex/HeaderMap.h"
#include "clang/Lex/HeaderSearchOptions.h"
#include "clang/Lex/LexDiagnostic.h"
using namespace clang;
const IdentifierInfo *
-HeaderFileInfo::getControllingMacro(ExternalIdentifierLookup *External) {
- if (ControllingMacro)
+HeaderFileInfo::getControllingMacro(ExternalPreprocessorSource *External) {
+ if (ControllingMacro) {
+ if (ControllingMacro->isOutOfDate())
+ External->updateOutOfDateIdentifier(
+ *const_cast<IdentifierInfo *>(ControllingMacro));
return ControllingMacro;
+ }
if (!ControllingMacroID || !External)
return nullptr;
#endif
#define A
+
+#include "c.h"
int m = n;
+#include "other.h"
+#include "c.h"
+
#if defined(A) && !defined(ALLOW_NAME_LEAKAGE)
#error A is defined
#endif
--- /dev/null
+#ifndef C_H_INCLUDED
+#define C_H_INCLUDED
+
+struct C {};
+
+#endif
module x { module a { header "a.h" } module b { header "b.h" } }
+module other { header "other.h" }
module cycles {
module cycle1 { header "cycle1.h" }
--- /dev/null
+#include "c.h"