summaryrefslogtreecommitdiffstats
path: root/include/clang/Lex/MacroInfo.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/clang/Lex/MacroInfo.h')
-rw-r--r--include/clang/Lex/MacroInfo.h119
1 files changed, 76 insertions, 43 deletions
diff --git a/include/clang/Lex/MacroInfo.h b/include/clang/Lex/MacroInfo.h
index e9a66e8..ca5d497 100644
--- a/include/clang/Lex/MacroInfo.h
+++ b/include/clang/Lex/MacroInfo.h
@@ -12,10 +12,11 @@
///
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_MACROINFO_H
-#define LLVM_CLANG_MACROINFO_H
+#ifndef LLVM_CLANG_LEX_MACROINFO_H
+#define LLVM_CLANG_LEX_MACROINFO_H
#include "clang/Lex/Token.h"
+#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/Support/Allocator.h"
#include <cassert>
@@ -45,7 +46,7 @@ class MacroInfo {
/// \see ArgumentList
unsigned NumArguments;
-
+
/// \brief This is the list of tokens that the macro is defined to.
SmallVector<Token, 8> ReplacementTokens;
@@ -78,8 +79,7 @@ class MacroInfo {
/// \brief Whether this macro contains the sequence ", ## __VA_ARGS__"
bool HasCommaPasting : 1;
-
-private:
+
//===--------------------------------------------------------------------===//
// State that changes as the macro is used.
@@ -107,28 +107,11 @@ private:
/// \brief Whether this macro was used as header guard.
bool UsedForHeaderGuard : 1;
- ~MacroInfo() {
- assert(!ArgumentList && "Didn't call destroy before dtor!");
- }
-
-public:
+ // Only the Preprocessor gets to create and destroy these.
MacroInfo(SourceLocation DefLoc);
-
- /// \brief Free the argument list of the macro.
- ///
- /// This restores this MacroInfo to a state where it can be reused for other
- /// devious purposes.
- void FreeArgumentList() {
- ArgumentList = nullptr;
- NumArguments = 0;
- }
-
- /// \brief Destroy this MacroInfo object.
- void Destroy() {
- FreeArgumentList();
- this->~MacroInfo();
- }
+ ~MacroInfo() {}
+public:
/// \brief Return the location that the macro was defined at.
SourceLocation getDefinitionLoc() const { return Location; }
@@ -350,9 +333,6 @@ protected:
// Used by DefMacroDirective -----------------------------------------------//
- /// \brief True if this macro was imported from a module.
- bool IsImported : 1;
-
/// \brief Whether the definition of this macro is ambiguous, due to
/// multiple definitions coming in from multiple modules.
bool IsAmbiguous : 1;
@@ -363,11 +343,35 @@ protected:
/// module).
bool IsPublic : 1;
- MacroDirective(Kind K, SourceLocation Loc)
- : Previous(nullptr), Loc(Loc), MDKind(K), IsFromPCH(false),
- IsImported(false), IsAmbiguous(false),
- IsPublic(true) {
- }
+ // Used by DefMacroDirective and UndefMacroDirective -----------------------//
+
+ /// \brief True if this macro was imported from a module.
+ bool IsImported : 1;
+
+ /// \brief For an imported directive, the number of modules whose macros are
+ /// overridden by this directive. Only used if IsImported.
+ unsigned NumOverrides : 26;
+
+ unsigned *getModuleDataStart();
+ const unsigned *getModuleDataStart() const {
+ return const_cast<MacroDirective*>(this)->getModuleDataStart();
+ }
+
+ MacroDirective(Kind K, SourceLocation Loc,
+ unsigned ImportedFromModuleID = 0,
+ ArrayRef<unsigned> Overrides = None)
+ : Previous(nullptr), Loc(Loc), MDKind(K), IsFromPCH(false),
+ IsAmbiguous(false), IsPublic(true), IsImported(ImportedFromModuleID),
+ NumOverrides(Overrides.size()) {
+ assert(NumOverrides == Overrides.size() && "too many overrides");
+ assert((IsImported || !NumOverrides) && "overrides for non-module macro");
+
+ if (IsImported) {
+ unsigned *Extra = getModuleDataStart();
+ *Extra++ = ImportedFromModuleID;
+ std::copy(Overrides.begin(), Overrides.end(), Extra);
+ }
+ }
public:
Kind getKind() const { return Kind(MDKind); }
@@ -390,6 +394,27 @@ public:
void setIsFromPCH() { IsFromPCH = true; }
+ /// \brief True if this macro was imported from a module.
+ /// Note that this is never the case for a VisibilityMacroDirective.
+ bool isImported() const { return IsImported; }
+
+ /// \brief If this directive was imported from a module, get the submodule
+ /// whose directive this is. Note that this may be different from the module
+ /// that owns the MacroInfo for a DefMacroDirective due to #pragma pop_macro
+ /// and similar effects.
+ unsigned getOwningModuleID() const {
+ if (isImported())
+ return *getModuleDataStart();
+ return 0;
+ }
+
+ /// \brief Get the module IDs of modules whose macros are overridden by this
+ /// directive. Only valid if this is an imported directive.
+ ArrayRef<unsigned> getOverriddenModules() const {
+ assert(IsImported && "can only get overridden modules for imported macro");
+ return llvm::makeArrayRef(getModuleDataStart() + 1, NumOverrides);
+ }
+
class DefInfo {
DefMacroDirective *DefDirective;
SourceLocation UndefLoc;
@@ -463,23 +488,22 @@ class DefMacroDirective : public MacroDirective {
public:
explicit DefMacroDirective(MacroInfo *MI)
- : MacroDirective(MD_Define, MI->getDefinitionLoc()), Info(MI) {
+ : MacroDirective(MD_Define, MI->getDefinitionLoc()), Info(MI) {
assert(MI && "MacroInfo is null");
}
- DefMacroDirective(MacroInfo *MI, SourceLocation Loc, bool isImported)
- : MacroDirective(MD_Define, Loc), Info(MI) {
+ DefMacroDirective(MacroInfo *MI, SourceLocation Loc,
+ unsigned ImportedFromModuleID = 0,
+ ArrayRef<unsigned> Overrides = None)
+ : MacroDirective(MD_Define, Loc, ImportedFromModuleID, Overrides),
+ Info(MI) {
assert(MI && "MacroInfo is null");
- IsImported = isImported;
}
/// \brief The data for the macro definition.
const MacroInfo *getInfo() const { return Info; }
MacroInfo *getInfo() { return Info; }
- /// \brief True if this macro was imported from a module.
- bool isImported() const { return IsImported; }
-
/// \brief Determine whether this macro definition is ambiguous with
/// other macro definitions.
bool isAmbiguous() const { return IsAmbiguous; }
@@ -496,9 +520,11 @@ public:
/// \brief A directive for an undefined macro.
class UndefMacroDirective : public MacroDirective {
public:
- explicit UndefMacroDirective(SourceLocation UndefLoc)
- : MacroDirective(MD_Undefine, UndefLoc) {
- assert(UndefLoc.isValid() && "Invalid UndefLoc!");
+ explicit UndefMacroDirective(SourceLocation UndefLoc,
+ unsigned ImportedFromModuleID = 0,
+ ArrayRef<unsigned> Overrides = None)
+ : MacroDirective(MD_Undefine, UndefLoc, ImportedFromModuleID, Overrides) {
+ assert((UndefLoc.isValid() || ImportedFromModuleID) && "Invalid UndefLoc!");
}
static bool classof(const MacroDirective *MD) {
@@ -525,6 +551,13 @@ public:
static bool classof(const VisibilityMacroDirective *) { return true; }
};
+inline unsigned *MacroDirective::getModuleDataStart() {
+ if (auto *Def = dyn_cast<DefMacroDirective>(this))
+ return reinterpret_cast<unsigned*>(Def + 1);
+ else
+ return reinterpret_cast<unsigned*>(cast<UndefMacroDirective>(this) + 1);
+}
+
inline SourceLocation MacroDirective::DefInfo::getLocation() const {
if (isInvalid())
return SourceLocation();
OpenPOWER on IntegriCloud