#include "clang/Lex/Token.h"
#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/FoldingSet.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/Support/Allocator.h"
#include <cassert>
return DefDirective->getPrevious()->getDefinition();
}
+/// \brief Represents a macro directive exported by a module.
+///
+/// There's an instance of this class for every macro #define or #undef that is
+/// the final directive for a macro name within a module. These entities also
+/// represent the macro override graph.
+///
+/// These are stored in a FoldingSet in the preprocessor.
+class ModuleMacro : public llvm::FoldingSetNode {
+ /// The name defined by the macro.
+ IdentifierInfo *II;
+ /// The body of the #define, or nullptr if this is a #undef.
+ MacroInfo *Macro;
+ /// The ID of the module that exports this macro.
+ unsigned OwningModuleID;
+ /// The number of module macros that override this one.
+ unsigned NumOverriddenBy;
+ /// The number of modules whose macros are directly overridden by this one.
+ unsigned NumOverrides;
+ //ModuleMacro *OverriddenMacros[NumOverrides];
+
+ friend class Preprocessor;
+
+ ModuleMacro(unsigned OwningModuleID, IdentifierInfo *II, MacroInfo *Macro,
+ ArrayRef<ModuleMacro *> Overrides)
+ : II(II), Macro(Macro), OwningModuleID(OwningModuleID),
+ NumOverriddenBy(0), NumOverrides(Overrides.size()) {
+ std::copy(Overrides.begin(), Overrides.end(),
+ reinterpret_cast<ModuleMacro **>(this + 1));
+ }
+
+public:
+ static ModuleMacro *create(Preprocessor &PP, unsigned OwningModuleID,
+ IdentifierInfo *II, MacroInfo *Macro,
+ ArrayRef<ModuleMacro *> Overrides);
+
+ void Profile(llvm::FoldingSetNodeID &ID) const {
+ return Profile(ID, OwningModuleID, II);
+ }
+ static void Profile(llvm::FoldingSetNodeID &ID, unsigned OwningModuleID,
+ IdentifierInfo *II) {
+ ID.AddInteger(OwningModuleID);
+ ID.AddPointer(II);
+ }
+
+ /// Get the ID of the module that exports this macro.
+ unsigned getOwningModuleID() const { return OwningModuleID; }
+
+ /// Get definition for this exported #define, or nullptr if this
+ /// represents a #undef.
+ MacroInfo *getMacroInfo() const { return Macro; }
+
+ /// Iterators over the overridden module IDs.
+ /// \{
+ typedef ModuleMacro *const *overrides_iterator;
+ overrides_iterator overrides_begin() const {
+ return reinterpret_cast<overrides_iterator>(this + 1);
+ }
+ overrides_iterator overrides_end() const {
+ return overrides_begin() + NumOverrides;
+ }
+ llvm::iterator_range<overrides_iterator> overrides() const {
+ return llvm::make_range(overrides_begin(), overrides_end());
+ }
+ /// \}
+};
+
} // end namespace clang
#endif
#include "llvm/ADT/IntrusiveRefCntPtr.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/TinyPtrVector.h"
#include "llvm/Support/Allocator.h"
#include <memory>
#include <vector>
/// the reverse order (the latest one is in the head of the list).
llvm::DenseMap<const IdentifierInfo*, MacroDirective*> Macros;
friend class ASTReader;
-
+
+ /// The set of known macros exported from modules.
+ llvm::FoldingSet<ModuleMacro> ModuleMacros;
+
+ /// The list of module macros, for each identifier, that are not overridden by
+ /// any other module macro.
+ llvm::DenseMap<const IdentifierInfo *, llvm::TinyPtrVector<ModuleMacro*>>
+ LeafModuleMacros;
+
/// \brief Macros that we want to warn because they are not used at the end
/// of the translation unit.
///
/// \c createPreprocessingRecord() prior to preprocessing.
PreprocessingRecord *Record;
-private: // Cached tokens state.
+ /// Cached tokens state.
typedef SmallVector<Token, 1> CachedTokensTy;
/// \brief Cached tokens are stored here when we do backtracking or
/// \brief Set a MacroDirective that was loaded from a PCH file.
void setLoadedMacroDirective(IdentifierInfo *II, MacroDirective *MD);
+ /// \brief Register an exported macro for a module and identifier.
+ ModuleMacro *addModuleMacro(unsigned ModuleID, IdentifierInfo *II,
+ MacroInfo *Macro,
+ ArrayRef<ModuleMacro *> Overrides, bool &IsNew);
+
/// \{
/// Iterators for the macro history table. Currently defined macros have
/// IdentifierInfo::hasMacroDefinition() set and an empty
void resolvePendingMacro(IdentifierInfo *II, const PendingMacroInfo &PMInfo);
- void installImportedMacro(IdentifierInfo *II, ModuleMacroInfo *MMI,
+ void installImportedMacro(IdentifierInfo *II, ModuleMacroInfo &MMI,
Module *Owner);
typedef llvm::TinyPtrVector<DefMacroDirective *> AmbiguousMacros;
}
Out << "\n";
}
+
+ModuleMacro *ModuleMacro::create(Preprocessor &PP, unsigned OwningModuleID,
+ IdentifierInfo *II, MacroInfo *Macro,
+ ArrayRef<ModuleMacro*> Overrides) {
+ return new (PP.getPreprocessorAllocator())
+ ModuleMacro(OwningModuleID, II, Macro, Overrides);
+}
II->setHasMacroDefinition(false);
}
+ModuleMacro *Preprocessor::addModuleMacro(unsigned ModuleID, IdentifierInfo *II,
+ MacroInfo *Macro,
+ ArrayRef<ModuleMacro *> Overrides,
+ bool &New) {
+ llvm::FoldingSetNodeID ID;
+ ModuleMacro::Profile(ID, ModuleID, II);
+
+ void *InsertPos;
+ if (auto *MM = ModuleMacros.FindNodeOrInsertPos(ID, InsertPos)) {
+ New = false;
+ return MM;
+ }
+
+ auto *MM = ModuleMacro::create(*this, ModuleID, II, Macro, Overrides);
+ ModuleMacros.InsertNode(MM, InsertPos);
+
+ // Each overridden macro is now overridden by one more macro.
+ bool HidAny = false;
+ for (auto *O : Overrides) {
+ HidAny |= (O->NumOverriddenBy == 0);
+ ++O->NumOverriddenBy;
+ }
+
+ // If we were the first overrider for any macro, it's no longer a leaf.
+ auto &LeafMacros = LeafModuleMacros[II];
+ if (HidAny) {
+ LeafMacros.erase(std::remove_if(LeafMacros.begin(), LeafMacros.end(),
+ [](ModuleMacro *MM) {
+ return MM->NumOverriddenBy != 0;
+ }),
+ LeafMacros.end());
+ }
+
+ // The new macro is always a leaf macro.
+ LeafMacros.push_back(MM);
+
+ New = true;
+ return MM;
+}
+
/// RegisterBuiltinMacro - Register the specified identifier in the identifier
/// table and mark it as a builtin macro to be expanded.
static IdentifierInfo *RegisterBuiltinMacro(Preprocessor &PP, const char *Name){
SavedStreamPosition SavedPosition(Cursor);
Cursor.JumpToBit(PMInfo.MacroDirectivesOffset);
- llvm::SmallVector<ModuleMacroInfo *, 8> ModuleMacros;
+ llvm::SmallVector<ModuleMacroInfo, 8> ModuleMacros;
// We expect to see a sequence of PP_MODULE_MACRO records listing exported
// macros, followed by a PP_MACRO_DIRECTIVE_HISTORY record with the complete
break;
case PP_MODULE_MACRO: {
- auto SubModID = getGlobalSubmoduleID(M, Record[0]);
- auto MacID = getGlobalMacroID(M, Record[1]);
-
- // Check whether we've already loaded this module macro.
- // FIXME: The MacrosLoaded check is wrong: multiple macro definitions can
- // have the same MacroInfo (and the same MacID) due to #pragma pop_macro.
- if (MacID ? (bool)MacrosLoaded[MacID - NUM_PREDEF_MACRO_IDS]
- : !LoadedUndefs.insert(std::make_pair(II, SubModID)).second)
- continue;
-
ModuleMacroInfo Info;
- Info.SubModID = SubModID;
- Info.MI = getMacro(MacID);
+ Info.SubModID = getGlobalSubmoduleID(M, Record[0]);
+ Info.MI = getMacro(getGlobalMacroID(M, Record[1]));
Info.F = &M;
if (Record.size() > 2) {
llvm::makeArrayRef(Overrides, Overrides + Record.size() - 2);
}
- ModuleMacros.push_back(new (Context) ModuleMacroInfo(Info));
+ ModuleMacros.push_back(Info);
continue;
}
}
// Module macros are listed in reverse dependency order.
- std::reverse(ModuleMacros.begin(), ModuleMacros.end());
- for (auto *MMI : ModuleMacros) {
- Module *Owner = getSubmodule(MMI->getSubmoduleID());
- if (Owner && Owner->NameVisibility == Module::Hidden) {
- // Macros in the owning module are hidden. Just remember this macro to
- // install if we make this module visible.
- HiddenNamesMap[Owner].HiddenMacros.insert(std::make_pair(II, MMI));
- } else {
- installImportedMacro(II, MMI, Owner);
+ {
+ std::reverse(ModuleMacros.begin(), ModuleMacros.end());
+ llvm::SmallDenseMap<unsigned, ModuleMacro*> Macros;
+ llvm::SmallVector<ModuleMacro*, 8> Overrides;
+ for (auto &MMI : ModuleMacros) {
+ Overrides.clear();
+ for (unsigned ModID : MMI.Overrides) {
+ auto *Macro = Macros.lookup(ModID);
+ assert(Macro && "missing definition for overridden macro");
+ Overrides.push_back(Macros.lookup(ModID));
+ }
+
+ bool Inserted = false;
+ Macros[MMI.SubModID] =
+ PP.addModuleMacro(MMI.SubModID, II, MMI.MI, Overrides, Inserted);
+ if (!Inserted)
+ continue;
+
+ Module *Owner = getSubmodule(MMI.getSubmoduleID());
+ if (Owner->NameVisibility == Module::Hidden) {
+ // Macros in the owning module are hidden. Just remember this macro to
+ // install if we make this module visible.
+ HiddenNamesMap[Owner].HiddenMacros.insert(
+ std::make_pair(II, new ModuleMacroInfo(MMI)));
+ } else {
+ installImportedMacro(II, MMI, Owner);
+ }
}
}
return nullptr;
}
-void ASTReader::installImportedMacro(IdentifierInfo *II, ModuleMacroInfo *MMI,
+void ASTReader::installImportedMacro(IdentifierInfo *II, ModuleMacroInfo &MMI,
Module *Owner) {
assert(II && Owner);
// source location for the import, we don't have a location for the macro.
// Use the location at which the containing module file was first imported
// for now.
- ImportLoc = MMI->F->DirectImportLoc;
+ ImportLoc = MMI.F->DirectImportLoc;
assert(ImportLoc.isValid() && "no import location for a visible macro?");
}
AmbiguousMacros *Prev =
- removeOverriddenMacros(II, ImportLoc, MMI->getOverriddenSubmodules());
+ removeOverriddenMacros(II, ImportLoc, MMI.getOverriddenSubmodules());
// Create a synthetic macro definition corresponding to the import (or null
// if this was an undefinition of the macro).
- MacroDirective *Imported = MMI->import(PP, ImportLoc);
+ MacroDirective *Imported = MMI.import(PP, ImportLoc);
DefMacroDirective *MD = dyn_cast<DefMacroDirective>(Imported);
// If there's no ambiguity, just install the macro.
PP.appendMacroDirective(Macro.first,
Macro.second->import(PP, SourceLocation()));
else
- installImportedMacro(Macro.first, Macro.second, Owner);
+ installImportedMacro(Macro.first, *Macro.second, Owner);
}
}