summaryrefslogtreecommitdiff
path: root/include/clang/Lex
diff options
context:
space:
mode:
Diffstat (limited to 'include/clang/Lex')
-rw-r--r--include/clang/Lex/ExternalPreprocessorSource.h4
-rw-r--r--include/clang/Lex/HeaderMap.h4
-rw-r--r--include/clang/Lex/HeaderSearch.h12
-rw-r--r--include/clang/Lex/Lexer.h24
-rw-r--r--include/clang/Lex/LiteralSupport.h14
-rw-r--r--include/clang/Lex/MacroArgs.h3
-rw-r--r--include/clang/Lex/MacroInfo.h236
-rw-r--r--include/clang/Lex/ModuleLoader.h3
-rw-r--r--include/clang/Lex/ModuleMap.h11
-rw-r--r--include/clang/Lex/PPCallbacks.h44
-rw-r--r--include/clang/Lex/PPConditionalDirectiveRecord.h4
-rw-r--r--include/clang/Lex/PTHLexer.h7
-rw-r--r--include/clang/Lex/PTHManager.h7
-rw-r--r--include/clang/Lex/Pragma.h2
-rw-r--r--include/clang/Lex/PreprocessingRecord.h226
-rw-r--r--include/clang/Lex/Preprocessor.h321
-rw-r--r--include/clang/Lex/PreprocessorLexer.h4
-rw-r--r--include/clang/Lex/Token.h19
-rw-r--r--include/clang/Lex/TokenLexer.h4
19 files changed, 593 insertions, 356 deletions
diff --git a/include/clang/Lex/ExternalPreprocessorSource.h b/include/clang/Lex/ExternalPreprocessorSource.h
index 2f9231dc9f22..33e7a2d84b88 100644
--- a/include/clang/Lex/ExternalPreprocessorSource.h
+++ b/include/clang/Lex/ExternalPreprocessorSource.h
@@ -17,6 +17,7 @@
namespace clang {
class IdentifierInfo;
+class Module;
/// \brief Abstract interface for external sources of preprocessor
/// information.
@@ -32,6 +33,9 @@ public:
/// \brief Update an out-of-date identifier.
virtual void updateOutOfDateIdentifier(IdentifierInfo &II) = 0;
+
+ /// \brief Map a module ID to a module.
+ virtual Module *getModule(unsigned ModuleID) = 0;
};
}
diff --git a/include/clang/Lex/HeaderMap.h b/include/clang/Lex/HeaderMap.h
index 993c8612b0f8..183361e4f8c0 100644
--- a/include/clang/Lex/HeaderMap.h
+++ b/include/clang/Lex/HeaderMap.h
@@ -32,8 +32,8 @@ namespace clang {
/// symlinks to files. Its advantages are that it is dense and more efficient
/// to create and process than a directory of symlinks.
class HeaderMap {
- HeaderMap(const HeaderMap &) LLVM_DELETED_FUNCTION;
- void operator=(const HeaderMap &) LLVM_DELETED_FUNCTION;
+ HeaderMap(const HeaderMap &) = delete;
+ void operator=(const HeaderMap &) = delete;
std::unique_ptr<const llvm::MemoryBuffer> FileBuffer;
bool NeedsBSwap;
diff --git a/include/clang/Lex/HeaderSearch.h b/include/clang/Lex/HeaderSearch.h
index 158f67d40b49..0406c6d586ff 100644
--- a/include/clang/Lex/HeaderSearch.h
+++ b/include/clang/Lex/HeaderSearch.h
@@ -32,6 +32,7 @@ class FileEntry;
class FileManager;
class HeaderSearchOptions;
class IdentifierInfo;
+class Preprocessor;
/// \brief The preprocessor keeps track of this information for each
/// file that is \#included.
@@ -255,8 +256,8 @@ class HeaderSearch {
const LangOptions &LangOpts;
// HeaderSearch doesn't support default or copy construction.
- HeaderSearch(const HeaderSearch&) LLVM_DELETED_FUNCTION;
- void operator=(const HeaderSearch&) LLVM_DELETED_FUNCTION;
+ HeaderSearch(const HeaderSearch&) = delete;
+ void operator=(const HeaderSearch&) = delete;
friend class DirectoryLookup;
@@ -419,8 +420,8 @@ public:
///
/// \return false if \#including the file will have no effect or true
/// if we should include it.
- bool ShouldEnterIncludeFile(const FileEntry *File, bool isImport);
-
+ bool ShouldEnterIncludeFile(Preprocessor &PP, const FileEntry *File,
+ bool isImport);
/// \brief Return whether the specified file is a normal header,
/// a system header, or a C++ friendly system header.
@@ -478,9 +479,6 @@ public:
/// FileEntry, uniquing them through the 'HeaderMaps' datastructure.
const HeaderMap *CreateHeaderMap(const FileEntry *FE);
- /// Returns true if modules are enabled.
- bool enabledModules() const { return LangOpts.Modules; }
-
/// \brief Retrieve the name of the module file that should be used to
/// load the given module.
///
diff --git a/include/clang/Lex/Lexer.h b/include/clang/Lex/Lexer.h
index c1f968be5584..07564b9de784 100644
--- a/include/clang/Lex/Lexer.h
+++ b/include/clang/Lex/Lexer.h
@@ -89,8 +89,8 @@ class Lexer : public PreprocessorLexer {
// CurrentConflictMarkerState - The kind of conflict marker we are handling.
ConflictMarkerKind CurrentConflictMarkerState;
- Lexer(const Lexer &) LLVM_DELETED_FUNCTION;
- void operator=(const Lexer &) LLVM_DELETED_FUNCTION;
+ Lexer(const Lexer &) = delete;
+ void operator=(const Lexer &) = delete;
friend class Preprocessor;
void InitLexer(const char *BufStart, const char *BufPtr, const char *BufEnd);
@@ -323,6 +323,26 @@ public:
const SourceManager &SM,
const LangOptions &LangOpts);
+ /// \brief Given a token range, produce a corresponding CharSourceRange that
+ /// is not a token range. This allows the source range to be used by
+ /// components that don't have access to the lexer and thus can't find the
+ /// end of the range for themselves.
+ static CharSourceRange getAsCharRange(SourceRange Range,
+ const SourceManager &SM,
+ const LangOptions &LangOpts) {
+ SourceLocation End = getLocForEndOfToken(Range.getEnd(), 0, SM, LangOpts);
+ return End.isInvalid() ? CharSourceRange()
+ : CharSourceRange::getCharRange(
+ Range.getBegin(), End.getLocWithOffset(-1));
+ }
+ static CharSourceRange getAsCharRange(CharSourceRange Range,
+ const SourceManager &SM,
+ const LangOptions &LangOpts) {
+ return Range.isTokenRange()
+ ? getAsCharRange(Range.getAsRange(), SM, LangOpts)
+ : Range;
+ }
+
/// \brief Returns true if the given MacroID location points at the first
/// token of the macro expansion.
///
diff --git a/include/clang/Lex/LiteralSupport.h b/include/clang/Lex/LiteralSupport.h
index f60a152a0aa9..5210e3f2e1c5 100644
--- a/include/clang/Lex/LiteralSupport.h
+++ b/include/clang/Lex/LiteralSupport.h
@@ -57,13 +57,13 @@ public:
NumericLiteralParser(StringRef TokSpelling,
SourceLocation TokLoc,
Preprocessor &PP);
- bool hadError;
- bool isUnsigned;
- bool isLong; // This is *not* set for long long.
- bool isLongLong;
- bool isFloat; // 1.0f
- bool isImaginary; // 1.0i
- uint8_t MicrosoftInteger; // Microsoft suffix extension i8, i16, i32, or i64.
+ bool hadError : 1;
+ bool isUnsigned : 1;
+ bool isLong : 1; // This is *not* set for long long.
+ bool isLongLong : 1;
+ bool isFloat : 1; // 1.0f
+ bool isImaginary : 1; // 1.0i
+ uint8_t MicrosoftInteger; // Microsoft suffix extension i8, i16, i32, or i64.
bool isIntegerLiteral() const {
return !saw_period && !saw_exponent;
diff --git a/include/clang/Lex/MacroArgs.h b/include/clang/Lex/MacroArgs.h
index d858ec2b4292..243b143f7af6 100644
--- a/include/clang/Lex/MacroArgs.h
+++ b/include/clang/Lex/MacroArgs.h
@@ -56,7 +56,8 @@ class MacroArgs {
MacroArgs(unsigned NumToks, bool varargsElided)
: NumUnexpArgTokens(NumToks), VarargsElided(varargsElided),
ArgCache(nullptr) {}
- ~MacroArgs() {}
+ ~MacroArgs() = default;
+
public:
/// MacroArgs ctor function - Create a new MacroArgs object with the specified
/// macro and argument info.
diff --git a/include/clang/Lex/MacroInfo.h b/include/clang/Lex/MacroInfo.h
index ca5d49704877..81d075cb000c 100644
--- a/include/clang/Lex/MacroInfo.h
+++ b/include/clang/Lex/MacroInfo.h
@@ -17,11 +17,15 @@
#include "clang/Lex/Token.h"
#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/FoldingSet.h"
+#include "llvm/ADT/PointerIntPair.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/Support/Allocator.h"
#include <cassert>
namespace clang {
+class Module;
+class ModuleMacro;
class Preprocessor;
/// \brief Encapsulates the data about a macro definition (e.g. its tokens).
@@ -109,7 +113,7 @@ class MacroInfo {
// Only the Preprocessor gets to create and destroy these.
MacroInfo(SourceLocation DefLoc);
- ~MacroInfo() {}
+ ~MacroInfo() = default;
public:
/// \brief Return the location that the macro was defined at.
@@ -241,6 +245,7 @@ public:
tokens_iterator tokens_begin() const { return ReplacementTokens.begin(); }
tokens_iterator tokens_end() const { return ReplacementTokens.end(); }
bool tokens_empty() const { return ReplacementTokens.empty(); }
+ ArrayRef<Token> tokens() const { return ReplacementTokens; }
/// \brief Add the specified token to the replacement text for the macro.
void AddTokenToBody(const Token &Tok) {
@@ -302,15 +307,8 @@ class DefMacroDirective;
///
/// MacroDirectives, associated with an identifier, are used to model the macro
/// history. Usually a macro definition (MacroInfo) is where a macro name
-/// becomes active (MacroDirective) but modules can have their own macro
-/// history, separate from the local (current translation unit) macro history.
-///
-/// For example, if "@import A;" imports macro FOO, there will be a new local
-/// MacroDirective created to indicate that "FOO" became active at the import
-/// location. Module "A" itself will contain another MacroDirective in its macro
-/// history (at the point of the definition of FOO) and both MacroDirectives
-/// will point to the same MacroInfo object.
-///
+/// becomes active (MacroDirective) but #pragma push_macro / pop_macro can
+/// create additional DefMacroDirectives for the same MacroInfo.
class MacroDirective {
public:
enum Kind {
@@ -331,47 +329,15 @@ protected:
/// \brief True if the macro directive was loaded from a PCH file.
bool IsFromPCH : 1;
- // Used by DefMacroDirective -----------------------------------------------//
-
- /// \brief Whether the definition of this macro is ambiguous, due to
- /// multiple definitions coming in from multiple modules.
- bool IsAmbiguous : 1;
-
// Used by VisibilityMacroDirective ----------------------------------------//
/// \brief Whether the macro has public visibility (when described in a
/// module).
bool IsPublic : 1;
- // 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)
+ MacroDirective(Kind K, SourceLocation Loc)
: 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);
- }
- }
+ IsPublic(true) {}
public:
Kind getKind() const { return Kind(MDKind); }
@@ -394,34 +360,13 @@ 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;
bool IsPublic;
public:
- DefInfo() : DefDirective(nullptr) { }
+ DefInfo() : DefDirective(nullptr), IsPublic(true) { }
DefInfo(DefMacroDirective *DefDirective, SourceLocation UndefLoc,
bool isPublic)
@@ -444,7 +389,7 @@ public:
bool isValid() const { return DefDirective != nullptr; }
bool isInvalid() const { return !isValid(); }
- LLVM_EXPLICIT operator bool() const { return isValid(); }
+ explicit operator bool() const { return isValid(); }
inline DefInfo getPreviousDefinition();
const DefInfo getPreviousDefinition() const {
@@ -487,30 +432,17 @@ class DefMacroDirective : public MacroDirective {
MacroInfo *Info;
public:
- explicit DefMacroDirective(MacroInfo *MI)
- : MacroDirective(MD_Define, MI->getDefinitionLoc()), Info(MI) {
- assert(MI && "MacroInfo is null");
- }
-
- DefMacroDirective(MacroInfo *MI, SourceLocation Loc,
- unsigned ImportedFromModuleID = 0,
- ArrayRef<unsigned> Overrides = None)
- : MacroDirective(MD_Define, Loc, ImportedFromModuleID, Overrides),
- Info(MI) {
+ DefMacroDirective(MacroInfo *MI, SourceLocation Loc)
+ : MacroDirective(MD_Define, Loc), Info(MI) {
assert(MI && "MacroInfo is null");
}
+ explicit DefMacroDirective(MacroInfo *MI)
+ : DefMacroDirective(MI, MI->getDefinitionLoc()) {}
/// \brief The data for the macro definition.
const MacroInfo *getInfo() const { return Info; }
MacroInfo *getInfo() { return Info; }
- /// \brief Determine whether this macro definition is ambiguous with
- /// other macro definitions.
- bool isAmbiguous() const { return IsAmbiguous; }
-
- /// \brief Set whether this macro definition is ambiguous.
- void setAmbiguous(bool Val) { IsAmbiguous = Val; }
-
static bool classof(const MacroDirective *MD) {
return MD->getKind() == MD_Define;
}
@@ -520,11 +452,9 @@ public:
/// \brief A directive for an undefined macro.
class UndefMacroDirective : public MacroDirective {
public:
- explicit UndefMacroDirective(SourceLocation UndefLoc,
- unsigned ImportedFromModuleID = 0,
- ArrayRef<unsigned> Overrides = None)
- : MacroDirective(MD_Undefine, UndefLoc, ImportedFromModuleID, Overrides) {
- assert((UndefLoc.isValid() || ImportedFromModuleID) && "Invalid UndefLoc!");
+ explicit UndefMacroDirective(SourceLocation UndefLoc)
+ : MacroDirective(MD_Undefine, UndefLoc) {
+ assert(UndefLoc.isValid() && "Invalid UndefLoc!");
}
static bool classof(const MacroDirective *MD) {
@@ -537,7 +467,7 @@ public:
class VisibilityMacroDirective : public MacroDirective {
public:
explicit VisibilityMacroDirective(SourceLocation Loc, bool Public)
- : MacroDirective(MD_Visibility, Loc) {
+ : MacroDirective(MD_Visibility, Loc) {
IsPublic = Public;
}
@@ -551,13 +481,6 @@ 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();
@@ -577,6 +500,123 @@ MacroDirective::DefInfo::getPreviousDefinition() {
return DefDirective->getPrevious()->getDefinition();
}
-} // end namespace clang
+/// \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 module that exports this macro.
+ Module *OwningModule;
+ /// 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(Module *OwningModule, IdentifierInfo *II, MacroInfo *Macro,
+ ArrayRef<ModuleMacro *> Overrides)
+ : II(II), Macro(Macro), OwningModule(OwningModule),
+ NumOverriddenBy(0), NumOverrides(Overrides.size()) {
+ std::copy(Overrides.begin(), Overrides.end(),
+ reinterpret_cast<ModuleMacro **>(this + 1));
+ }
+
+public:
+ static ModuleMacro *create(Preprocessor &PP, Module *OwningModule,
+ IdentifierInfo *II, MacroInfo *Macro,
+ ArrayRef<ModuleMacro *> Overrides);
+
+ void Profile(llvm::FoldingSetNodeID &ID) const {
+ return Profile(ID, OwningModule, II);
+ }
+ static void Profile(llvm::FoldingSetNodeID &ID, Module *OwningModule,
+ IdentifierInfo *II) {
+ ID.AddPointer(OwningModule);
+ ID.AddPointer(II);
+ }
+
+ /// Get the ID of the module that exports this macro.
+ Module *getOwningModule() const { return OwningModule; }
+
+ /// 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;
+ }
+ ArrayRef<ModuleMacro *> overrides() const {
+ return llvm::makeArrayRef(overrides_begin(), overrides_end());
+ }
+ /// \}
+
+ /// Get the number of macros that override this one.
+ unsigned getNumOverridingMacros() const { return NumOverriddenBy; }
+};
+
+/// \brief A description of the current definition of a macro.
+///
+/// The definition of a macro comprises a set of (at least one) defining
+/// entities, which are either local MacroDirectives or imported ModuleMacros.
+class MacroDefinition {
+ llvm::PointerIntPair<DefMacroDirective *, 1, bool> LatestLocalAndAmbiguous;
+ ArrayRef<ModuleMacro *> ModuleMacros;
+
+public:
+ MacroDefinition() : LatestLocalAndAmbiguous(), ModuleMacros() {}
+ MacroDefinition(DefMacroDirective *MD, ArrayRef<ModuleMacro *> MMs,
+ bool IsAmbiguous)
+ : LatestLocalAndAmbiguous(MD, IsAmbiguous), ModuleMacros(MMs) {}
+
+ /// \brief Determine whether there is a definition of this macro.
+ explicit operator bool() const {
+ return getLocalDirective() || !ModuleMacros.empty();
+ }
+
+ /// \brief Get the MacroInfo that should be used for this definition.
+ MacroInfo *getMacroInfo() const {
+ if (!ModuleMacros.empty())
+ return ModuleMacros.back()->getMacroInfo();
+ if (auto *MD = getLocalDirective())
+ return MD->getMacroInfo();
+ return nullptr;
+ }
+
+ /// \brief \c true if the definition is ambiguous, \c false otherwise.
+ bool isAmbiguous() const { return LatestLocalAndAmbiguous.getInt(); }
+
+ /// \brief Get the latest non-imported, non-\#undef'd macro definition
+ /// for this macro.
+ DefMacroDirective *getLocalDirective() const {
+ return LatestLocalAndAmbiguous.getPointer();
+ }
+
+ /// \brief Get the active module macros for this macro.
+ ArrayRef<ModuleMacro *> getModuleMacros() const { return ModuleMacros; }
+
+ template <typename Fn> void forAllDefinitions(Fn F) const {
+ if (auto *MD = getLocalDirective())
+ F(MD->getMacroInfo());
+ for (auto *MM : getModuleMacros())
+ F(MM->getMacroInfo());
+ }
+};
+
+} // end namespace clang
#endif
diff --git a/include/clang/Lex/ModuleLoader.h b/include/clang/Lex/ModuleLoader.h
index 36605c9c18c6..ae79650d1fd0 100644
--- a/include/clang/Lex/ModuleLoader.h
+++ b/include/clang/Lex/ModuleLoader.h
@@ -99,8 +99,7 @@ public:
/// \brief Make the given module visible.
virtual void makeModuleVisible(Module *Mod,
Module::NameVisibilityKind Visibility,
- SourceLocation ImportLoc,
- bool Complain) = 0;
+ SourceLocation ImportLoc) = 0;
/// \brief Load, create, or return global module.
/// This function returns an existing global module index, if one
diff --git a/include/clang/Lex/ModuleMap.h b/include/clang/Lex/ModuleMap.h
index ed885a7410d5..83a410dfc9e8 100644
--- a/include/clang/Lex/ModuleMap.h
+++ b/include/clang/Lex/ModuleMap.h
@@ -64,6 +64,9 @@ private:
/// \brief The top-level modules that are known.
llvm::StringMap<Module *> Modules;
+ /// \brief The number of modules we have created in total.
+ unsigned NumCreatedModules;
+
public:
/// \brief Flags describing the role of a module header.
enum ModuleHeaderRole {
@@ -104,7 +107,7 @@ public:
// \brief Whether this known header is valid (i.e., it has an
// associated module).
- LLVM_EXPLICIT operator bool() const {
+ explicit operator bool() const {
return Storage.getPointer() != nullptr;
}
};
@@ -434,11 +437,13 @@ public:
/// \brief Sets the umbrella header of the given module to the given
/// header.
- void setUmbrellaHeader(Module *Mod, const FileEntry *UmbrellaHeader);
+ void setUmbrellaHeader(Module *Mod, const FileEntry *UmbrellaHeader,
+ Twine NameAsWritten);
/// \brief Sets the umbrella directory of the given module to the given
/// directory.
- void setUmbrellaDir(Module *Mod, const DirectoryEntry *UmbrellaDir);
+ void setUmbrellaDir(Module *Mod, const DirectoryEntry *UmbrellaDir,
+ Twine NameAsWritten);
/// \brief Adds this header to the given module.
/// \param Role The role of the header wrt the module.
diff --git a/include/clang/Lex/PPCallbacks.h b/include/clang/Lex/PPCallbacks.h
index 056c58aa3348..1ddb5d61eff5 100644
--- a/include/clang/Lex/PPCallbacks.h
+++ b/include/clang/Lex/PPCallbacks.h
@@ -27,6 +27,7 @@ namespace clang {
class SourceLocation;
class Token;
class IdentifierInfo;
+ class MacroDefinition;
class MacroDirective;
class MacroArgs;
@@ -54,11 +55,12 @@ public:
/// \brief Callback invoked whenever a source file is skipped as the result
/// of header guard optimization.
///
- /// \param ParentFile The file that \#included the skipped file.
+ /// \param SkippedFile The file that is skipped instead of entering \#include
///
- /// \param FilenameTok The token in ParentFile that indicates the
- /// skipped file.
- virtual void FileSkipped(const FileEntry &ParentFile,
+ /// \param FilenameTok The file name token in \#include "FileName" directive
+ /// or macro expanded file name token from \#include MACRO(PARAMS) directive.
+ /// Note that FilenameTok contains corresponding quotes/angles symbols.
+ virtual void FileSkipped(const FileEntry &SkippedFile,
const Token &FilenameTok,
SrcMgr::CharacteristicKind FileType) {
}
@@ -238,9 +240,9 @@ public:
/// \brief Called by Preprocessor::HandleMacroExpandedIdentifier when a
/// macro invocation is found.
- virtual void MacroExpands(const Token &MacroNameTok, const MacroDirective *MD,
- SourceRange Range, const MacroArgs *Args) {
- }
+ virtual void MacroExpands(const Token &MacroNameTok,
+ const MacroDefinition &MD, SourceRange Range,
+ const MacroArgs *Args) {}
/// \brief Hook called whenever a macro definition is seen.
virtual void MacroDefined(const Token &MacroNameTok,
@@ -251,12 +253,12 @@ public:
///
/// MD is released immediately following this callback.
virtual void MacroUndefined(const Token &MacroNameTok,
- const MacroDirective *MD) {
+ const MacroDefinition &MD) {
}
/// \brief Hook called whenever the 'defined' operator is seen.
/// \param MD The MacroDirective if the name was a macro, null otherwise.
- virtual void Defined(const Token &MacroNameTok, const MacroDirective *MD,
+ virtual void Defined(const Token &MacroNameTok, const MacroDefinition &MD,
SourceRange Range) {
}
@@ -293,17 +295,17 @@ public:
/// \brief Hook called whenever an \#ifdef is seen.
/// \param Loc the source location of the directive.
/// \param MacroNameTok Information on the token being tested.
- /// \param MD The MacroDirective if the name was a macro, null otherwise.
+ /// \param MD The MacroDefinition if the name was a macro, null otherwise.
virtual void Ifdef(SourceLocation Loc, const Token &MacroNameTok,
- const MacroDirective *MD) {
+ const MacroDefinition &MD) {
}
/// \brief Hook called whenever an \#ifndef is seen.
/// \param Loc the source location of the directive.
/// \param MacroNameTok Information on the token being tested.
- /// \param MD The MacroDirective if the name was a macro, null otherwise.
+ /// \param MD The MacroDefiniton if the name was a macro, null otherwise.
virtual void Ifndef(SourceLocation Loc, const Token &MacroNameTok,
- const MacroDirective *MD) {
+ const MacroDefinition &MD) {
}
/// \brief Hook called whenever an \#else is seen.
@@ -336,11 +338,11 @@ public:
Second->FileChanged(Loc, Reason, FileType, PrevFID);
}
- void FileSkipped(const FileEntry &ParentFile,
+ void FileSkipped(const FileEntry &SkippedFile,
const Token &FilenameTok,
SrcMgr::CharacteristicKind FileType) override {
- First->FileSkipped(ParentFile, FilenameTok, FileType);
- Second->FileSkipped(ParentFile, FilenameTok, FileType);
+ First->FileSkipped(SkippedFile, FilenameTok, FileType);
+ Second->FileSkipped(SkippedFile, FilenameTok, FileType);
}
bool FileNotFound(StringRef FileName,
@@ -434,7 +436,7 @@ public:
Second->PragmaWarningPop(Loc);
}
- void MacroExpands(const Token &MacroNameTok, const MacroDirective *MD,
+ void MacroExpands(const Token &MacroNameTok, const MacroDefinition &MD,
SourceRange Range, const MacroArgs *Args) override {
First->MacroExpands(MacroNameTok, MD, Range, Args);
Second->MacroExpands(MacroNameTok, MD, Range, Args);
@@ -446,12 +448,12 @@ public:
}
void MacroUndefined(const Token &MacroNameTok,
- const MacroDirective *MD) override {
+ const MacroDefinition &MD) override {
First->MacroUndefined(MacroNameTok, MD);
Second->MacroUndefined(MacroNameTok, MD);
}
- void Defined(const Token &MacroNameTok, const MacroDirective *MD,
+ void Defined(const Token &MacroNameTok, const MacroDefinition &MD,
SourceRange Range) override {
First->Defined(MacroNameTok, MD, Range);
Second->Defined(MacroNameTok, MD, Range);
@@ -478,14 +480,14 @@ public:
/// \brief Hook called whenever an \#ifdef is seen.
void Ifdef(SourceLocation Loc, const Token &MacroNameTok,
- const MacroDirective *MD) override {
+ const MacroDefinition &MD) override {
First->Ifdef(Loc, MacroNameTok, MD);
Second->Ifdef(Loc, MacroNameTok, MD);
}
/// \brief Hook called whenever an \#ifndef is seen.
void Ifndef(SourceLocation Loc, const Token &MacroNameTok,
- const MacroDirective *MD) override {
+ const MacroDefinition &MD) override {
First->Ifndef(Loc, MacroNameTok, MD);
Second->Ifndef(Loc, MacroNameTok, MD);
}
diff --git a/include/clang/Lex/PPConditionalDirectiveRecord.h b/include/clang/Lex/PPConditionalDirectiveRecord.h
index 00d2d5797359..8c5227561b83 100644
--- a/include/clang/Lex/PPConditionalDirectiveRecord.h
+++ b/include/clang/Lex/PPConditionalDirectiveRecord.h
@@ -91,9 +91,9 @@ private:
void Elif(SourceLocation Loc, SourceRange ConditionRange,
ConditionValueKind ConditionValue, SourceLocation IfLoc) override;
void Ifdef(SourceLocation Loc, const Token &MacroNameTok,
- const MacroDirective *MD) override;
+ const MacroDefinition &MD) override;
void Ifndef(SourceLocation Loc, const Token &MacroNameTok,
- const MacroDirective *MD) override;
+ const MacroDefinition &MD) override;
void Else(SourceLocation Loc, SourceLocation IfLoc) override;
void Endif(SourceLocation Loc, SourceLocation IfLoc) override;
};
diff --git a/include/clang/Lex/PTHLexer.h b/include/clang/Lex/PTHLexer.h
index 54c91f6b0860..904be792b2a9 100644
--- a/include/clang/Lex/PTHLexer.h
+++ b/include/clang/Lex/PTHLexer.h
@@ -44,8 +44,8 @@ class PTHLexer : public PreprocessorLexer {
/// to process when doing quick skipping of preprocessor blocks.
const unsigned char* CurPPCondPtr;
- PTHLexer(const PTHLexer &) LLVM_DELETED_FUNCTION;
- void operator=(const PTHLexer &) LLVM_DELETED_FUNCTION;
+ PTHLexer(const PTHLexer &) = delete;
+ void operator=(const PTHLexer &) = delete;
/// ReadToken - Used by PTHLexer to read tokens TokBuf.
void ReadToken(Token& T);
@@ -64,8 +64,7 @@ protected:
PTHLexer(Preprocessor& pp, FileID FID, const unsigned char *D,
const unsigned char* ppcond, PTHManager &PM);
public:
-
- ~PTHLexer() {}
+ ~PTHLexer() override {}
/// Lex - Return the next token.
bool Lex(Token &Tok);
diff --git a/include/clang/Lex/PTHManager.h b/include/clang/Lex/PTHManager.h
index 64ecf5f575f3..a4198f890e13 100644
--- a/include/clang/Lex/PTHManager.h
+++ b/include/clang/Lex/PTHManager.h
@@ -19,6 +19,7 @@
#include "clang/Basic/LangOptions.h"
#include "clang/Lex/PTHLexer.h"
#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/STLExtras.h"
#include "llvm/Support/Allocator.h"
#include "llvm/Support/OnDiskHashTable.h"
#include <string>
@@ -91,8 +92,8 @@ class PTHManager : public IdentifierInfoLookup {
std::unique_ptr<PTHStringIdLookup> stringIdLookup, unsigned numIds,
const unsigned char *spellingBase, const char *originalSourceFile);
- PTHManager(const PTHManager &) LLVM_DELETED_FUNCTION;
- void operator=(const PTHManager &) LLVM_DELETED_FUNCTION;
+ PTHManager(const PTHManager &) = delete;
+ void operator=(const PTHManager &) = delete;
/// getSpellingAtPTHOffset - Used by PTHLexer classes to get the cached
/// spelling for a token.
@@ -112,7 +113,7 @@ public:
// The current PTH version.
enum { Version = 10 };
- ~PTHManager();
+ ~PTHManager() override;
/// getOriginalSourceFile - Return the full path to the original header
/// file name that was used to generate the PTH cache.
diff --git a/include/clang/Lex/Pragma.h b/include/clang/Lex/Pragma.h
index 4123bae2ea3a..70fcfda6e754 100644
--- a/include/clang/Lex/Pragma.h
+++ b/include/clang/Lex/Pragma.h
@@ -93,7 +93,7 @@ class PragmaNamespace : public PragmaHandler {
llvm::StringMap<PragmaHandler*> Handlers;
public:
explicit PragmaNamespace(StringRef Name) : PragmaHandler(Name) {}
- virtual ~PragmaNamespace();
+ ~PragmaNamespace() override;
/// FindHandler - Check to see if there is already a handler for the
/// specified name. If not, return the handler for the null name if it
diff --git a/include/clang/Lex/PreprocessingRecord.h b/include/clang/Lex/PreprocessingRecord.h
index 4609fe3c68f8..53367ab854f2 100644
--- a/include/clang/Lex/PreprocessingRecord.h
+++ b/include/clang/Lex/PreprocessingRecord.h
@@ -20,6 +20,7 @@
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/Optional.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/iterator.h"
#include "llvm/Support/Allocator.h"
#include "llvm/Support/Compiler.h"
#include <vector>
@@ -35,11 +36,11 @@ void* operator new(size_t bytes, clang::PreprocessingRecord& PR,
unsigned alignment = 8) throw();
/// \brief Frees memory allocated in a Clang preprocessing record.
-void operator delete(void* ptr, clang::PreprocessingRecord& PR,
+void operator delete(void *ptr, clang::PreprocessingRecord &PR,
unsigned) throw();
namespace clang {
- class MacroDefinition;
+ class MacroDefinitionRecord;
class FileEntry;
/// \brief Base class that describes a preprocessed entity, which may be a
@@ -132,19 +133,20 @@ namespace clang {
PD->getKind() <= LastPreprocessingDirective;
}
};
-
+
/// \brief Record the location of a macro definition.
- class MacroDefinition : public PreprocessingDirective {
+ class MacroDefinitionRecord : public PreprocessingDirective {
/// \brief The name of the macro being defined.
const IdentifierInfo *Name;
public:
- explicit MacroDefinition(const IdentifierInfo *Name, SourceRange Range)
- : PreprocessingDirective(MacroDefinitionKind, Range), Name(Name) { }
-
+ explicit MacroDefinitionRecord(const IdentifierInfo *Name,
+ SourceRange Range)
+ : PreprocessingDirective(MacroDefinitionKind, Range), Name(Name) {}
+
/// \brief Retrieve the name of the macro being defined.
const IdentifierInfo *getName() const { return Name; }
-
+
/// \brief Retrieve the location of the macro name in the definition.
SourceLocation getLocation() const { return getSourceRange().getBegin(); }
@@ -158,31 +160,31 @@ namespace clang {
class MacroExpansion : public PreprocessedEntity {
/// \brief The definition of this macro or the name of the macro if it is
/// a builtin macro.
- llvm::PointerUnion<IdentifierInfo *, MacroDefinition *> NameOrDef;
+ llvm::PointerUnion<IdentifierInfo *, MacroDefinitionRecord *> NameOrDef;
public:
MacroExpansion(IdentifierInfo *BuiltinName, SourceRange Range)
- : PreprocessedEntity(MacroExpansionKind, Range),
- NameOrDef(BuiltinName) { }
+ : PreprocessedEntity(MacroExpansionKind, Range),
+ NameOrDef(BuiltinName) {}
- MacroExpansion(MacroDefinition *Definition, SourceRange Range)
- : PreprocessedEntity(MacroExpansionKind, Range),
- NameOrDef(Definition) { }
+ MacroExpansion(MacroDefinitionRecord *Definition, SourceRange Range)
+ : PreprocessedEntity(MacroExpansionKind, Range), NameOrDef(Definition) {
+ }
/// \brief True if it is a builtin macro.
bool isBuiltinMacro() const { return NameOrDef.is<IdentifierInfo *>(); }
-
+
/// \brief The name of the macro being expanded.
const IdentifierInfo *getName() const {
- if (MacroDefinition *Def = getDefinition())
+ if (MacroDefinitionRecord *Def = getDefinition())
return Def->getName();
- return NameOrDef.get<IdentifierInfo*>();
+ return NameOrDef.get<IdentifierInfo *>();
}
-
+
/// \brief The definition of the macro being expanded. May return null if
/// this is a builtin macro.
- MacroDefinition *getDefinition() const {
- return NameOrDef.dyn_cast<MacroDefinition *>();
+ MacroDefinitionRecord *getDefinition() const {
+ return NameOrDef.dyn_cast<MacroDefinitionRecord *>();
}
// Implement isa/cast/dyncast/etc.
@@ -329,7 +331,7 @@ namespace clang {
}
/// \brief Mapping from MacroInfo structures to their definitions.
- llvm::DenseMap<const MacroInfo *, MacroDefinition *> MacroDefinitions;
+ llvm::DenseMap<const MacroInfo *, MacroDefinitionRecord *> MacroDefinitions;
/// \brief External source of preprocessed entities.
ExternalPreprocessingRecordSource *ExternalSource;
@@ -360,12 +362,12 @@ namespace clang {
unsigned allocateLoadedEntities(unsigned NumEntities);
/// \brief Register a new macro definition.
- void RegisterMacroDefinition(MacroInfo *Macro, MacroDefinition *Def);
-
+ void RegisterMacroDefinition(MacroInfo *Macro, MacroDefinitionRecord *Def);
+
public:
/// \brief Construct a new preprocessing record.
explicit PreprocessingRecord(SourceManager &SM);
-
+
/// \brief Allocate memory in the preprocessing record.
void *Allocate(unsigned Size, unsigned Align = 8) {
return BumpAlloc.Allocate(Size, Align);
@@ -378,125 +380,44 @@ namespace clang {
SourceManager &getSourceManager() const { return SourceMgr; }
- // Iteration over the preprocessed entities.
- class iterator {
+ /// Iteration over the preprocessed entities.
+ ///
+ /// In a complete iteration, the iterator walks the range [-M, N),
+ /// where negative values are used to indicate preprocessed entities
+ /// loaded from the external source while non-negative values are used to
+ /// indicate preprocessed entities introduced by the current preprocessor.
+ /// However, to provide iteration in source order (for, e.g., chained
+ /// precompiled headers), dereferencing the iterator flips the negative
+ /// values (corresponding to loaded entities), so that position -M
+ /// corresponds to element 0 in the loaded entities vector, position -M+1
+ /// corresponds to element 1 in the loaded entities vector, etc. This
+ /// gives us a reasonably efficient, source-order walk.
+ ///
+ /// We define this as a wrapping iterator around an int. The
+ /// iterator_adaptor_base class forwards the iterator methods to basic
+ /// integer arithmetic.
+ class iterator : public llvm::iterator_adaptor_base<
+ iterator, int, std::random_access_iterator_tag,
+ PreprocessedEntity *, int, PreprocessedEntity *,
+ PreprocessedEntity *> {
PreprocessingRecord *Self;
-
- /// \brief Position within the preprocessed entity sequence.
- ///
- /// In a complete iteration, the Position field walks the range [-M, N),
- /// where negative values are used to indicate preprocessed entities
- /// loaded from the external source while non-negative values are used to
- /// indicate preprocessed entities introduced by the current preprocessor.
- /// However, to provide iteration in source order (for, e.g., chained
- /// precompiled headers), dereferencing the iterator flips the negative
- /// values (corresponding to loaded entities), so that position -M
- /// corresponds to element 0 in the loaded entities vector, position -M+1
- /// corresponds to element 1 in the loaded entities vector, etc. This
- /// gives us a reasonably efficient, source-order walk.
- int Position;
-
- public:
- typedef PreprocessedEntity *value_type;
- typedef value_type& reference;
- typedef value_type* pointer;
- typedef std::random_access_iterator_tag iterator_category;
- typedef int difference_type;
-
- iterator() : Self(nullptr), Position(0) { }
-
+
iterator(PreprocessingRecord *Self, int Position)
- : Self(Self), Position(Position) { }
-
- value_type operator*() const {
- bool isLoaded = Position < 0;
+ : iterator::iterator_adaptor_base(Position), Self(Self) {}
+ friend class PreprocessingRecord;
+
+ public:
+ iterator() : iterator(nullptr, 0) {}
+
+ PreprocessedEntity *operator*() const {
+ bool isLoaded = this->I < 0;
unsigned Index = isLoaded ?
- Self->LoadedPreprocessedEntities.size() + Position : Position;
+ Self->LoadedPreprocessedEntities.size() + this->I : this->I;
PPEntityID ID = Self->getPPEntityID(Index, isLoaded);
return Self->getPreprocessedEntity(ID);
}
-
- value_type operator[](difference_type D) {
- return *(*this + D);
- }
-
- iterator &operator++() {
- ++Position;
- return *this;
- }
-
- iterator operator++(int) {
- iterator Prev(*this);
- ++Position;
- return Prev;
- }
-
- iterator &operator--() {
- --Position;
- return *this;
- }
-
- iterator operator--(int) {
- iterator Prev(*this);
- --Position;
- return Prev;
- }
-
- friend bool operator==(const iterator &X, const iterator &Y) {
- return X.Position == Y.Position;
- }
-
- friend bool operator!=(const iterator &X, const iterator &Y) {
- return X.Position != Y.Position;
- }
-
- friend bool operator<(const iterator &X, const iterator &Y) {
- return X.Position < Y.Position;
- }
-
- friend bool operator>(const iterator &X, const iterator &Y) {
- return X.Position > Y.Position;
- }
-
- friend bool operator<=(const iterator &X, const iterator &Y) {
- return X.Position < Y.Position;
- }
-
- friend bool operator>=(const iterator &X, const iterator &Y) {
- return X.Position > Y.Position;
- }
-
- friend iterator& operator+=(iterator &X, difference_type D) {
- X.Position += D;
- return X;
- }
-
- friend iterator& operator-=(iterator &X, difference_type D) {
- X.Position -= D;
- return X;
- }
-
- friend iterator operator+(iterator X, difference_type D) {
- X.Position += D;
- return X;
- }
-
- friend iterator operator+(difference_type D, iterator X) {
- X.Position += D;
- return X;
- }
-
- friend difference_type operator-(const iterator &X, const iterator &Y) {
- return X.Position - Y.Position;
- }
-
- friend iterator operator-(iterator X, difference_type D) {
- X.Position -= D;
- return X;
- }
- friend class PreprocessingRecord;
+ PreprocessedEntity *operator->() const { return **this; }
};
- friend class iterator;
/// \brief Begin iterator for all preprocessed entities.
iterator begin() {
@@ -518,23 +439,24 @@ namespace clang {
return iterator(this, PreprocessedEntities.size());
}
- /// \brief begin/end iterator pair for the given range of loaded
+ /// \brief iterator range for the given range of loaded
/// preprocessed entities.
- std::pair<iterator, iterator>
- getIteratorsForLoadedRange(unsigned start, unsigned count) {
+ llvm::iterator_range<iterator> getIteratorsForLoadedRange(unsigned start,
+ unsigned count) {
unsigned end = start + count;
assert(end <= LoadedPreprocessedEntities.size());
- return std::make_pair(
- iterator(this, int(start)-LoadedPreprocessedEntities.size()),
- iterator(this, int(end)-LoadedPreprocessedEntities.size()));
+ return llvm::make_range(
+ iterator(this, int(start) - LoadedPreprocessedEntities.size()),
+ iterator(this, int(end) - LoadedPreprocessedEntities.size()));
}
- /// \brief Returns a pair of [Begin, End) iterators of preprocessed entities
- /// that source range \p R encompasses.
+ /// \brief Returns a range of preprocessed entities that source range \p R
+ /// encompasses.
///
/// \param R the range to look for preprocessed entities.
///
- std::pair<iterator, iterator> getPreprocessedEntitiesInRange(SourceRange R);
+ llvm::iterator_range<iterator>
+ getPreprocessedEntitiesInRange(SourceRange R);
/// \brief Returns true if the preprocessed entity that \p PPEI iterator
/// points to is coming from the file \p FID.
@@ -555,10 +477,10 @@ namespace clang {
ExternalPreprocessingRecordSource *getExternalSource() const {
return ExternalSource;
}
-
+
/// \brief Retrieve the macro definition that corresponds to the given
/// \c MacroInfo.
- MacroDefinition *findMacroDefinition(const MacroInfo *MI);
+ MacroDefinitionRecord *findMacroDefinition(const MacroInfo *MI);
/// \brief Retrieve all ranges that got skipped while preprocessing.
const std::vector<SourceRange> &getSkippedRanges() const {
@@ -566,10 +488,10 @@ namespace clang {
}
private:
- void MacroExpands(const Token &Id, const MacroDirective *MD,
+ void MacroExpands(const Token &Id, const MacroDefinition &MD,
SourceRange Range, const MacroArgs *Args) override;
void MacroDefined(const Token &Id, const MacroDirective *MD) override;
- void MacroUndefined(const Token &Id, const MacroDirective *MD) override;
+ void MacroUndefined(const Token &Id, const MacroDefinition &MD) override;
void InclusionDirective(SourceLocation HashLoc, const Token &IncludeTok,
StringRef FileName, bool IsAngled,
CharSourceRange FilenameRange,
@@ -577,11 +499,11 @@ namespace clang {
StringRef RelativePath,
const Module *Imported) override;
void Ifdef(SourceLocation Loc, const Token &MacroNameTok,
- const MacroDirective *MD) override;
+ const MacroDefinition &MD) override;
void Ifndef(SourceLocation Loc, const Token &MacroNameTok,
- const MacroDirective *MD) override;
+ const MacroDefinition &MD) override;
/// \brief Hook called whenever the 'defined' operator is seen.
- void Defined(const Token &MacroNameTok, const MacroDirective *MD,
+ void Defined(const Token &MacroNameTok, const MacroDefinition &MD,
SourceRange Range) override;
void SourceRangeSkipped(SourceRange Range) override;
diff --git a/include/clang/Lex/Preprocessor.h b/include/clang/Lex/Preprocessor.h
index 326f519e914e..ea15dbdf2144 100644
--- a/include/clang/Lex/Preprocessor.h
+++ b/include/clang/Lex/Preprocessor.h
@@ -31,6 +31,7 @@
#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>
@@ -356,19 +357,185 @@ class Preprocessor : public RefCountedBase<Preprocessor> {
struct MacroExpandsInfo {
Token Tok;
- MacroDirective *MD;
+ MacroDefinition MD;
SourceRange Range;
- MacroExpandsInfo(Token Tok, MacroDirective *MD, SourceRange Range)
+ MacroExpandsInfo(Token Tok, MacroDefinition MD, SourceRange Range)
: Tok(Tok), MD(MD), Range(Range) { }
};
SmallVector<MacroExpandsInfo, 2> DelayedMacroExpandsCallbacks;
+ /// Information about a name that has been used to define a module macro.
+ struct ModuleMacroInfo {
+ ModuleMacroInfo(MacroDirective *MD)
+ : MD(MD), ActiveModuleMacrosGeneration(0), IsAmbiguous(false) {}
+
+ /// The most recent macro directive for this identifier.
+ MacroDirective *MD;
+ /// The active module macros for this identifier.
+ llvm::TinyPtrVector<ModuleMacro*> ActiveModuleMacros;
+ /// The generation number at which we last updated ActiveModuleMacros.
+ /// \see Preprocessor::VisibleModules.
+ unsigned ActiveModuleMacrosGeneration;
+ /// Whether this macro name is ambiguous.
+ bool IsAmbiguous;
+ /// The module macros that are overridden by this macro.
+ llvm::TinyPtrVector<ModuleMacro*> OverriddenMacros;
+ };
+
+ /// The state of a macro for an identifier.
+ class MacroState {
+ mutable llvm::PointerUnion<MacroDirective *, ModuleMacroInfo *> State;
+
+ ModuleMacroInfo *getModuleInfo(Preprocessor &PP,
+ const IdentifierInfo *II) const {
+ // FIXME: Find a spare bit on IdentifierInfo and store a
+ // HasModuleMacros flag.
+ if (!II->hasMacroDefinition() || !PP.getLangOpts().Modules ||
+ !PP.CurSubmoduleState->VisibleModules.getGeneration())
+ return nullptr;
+
+ auto *Info = State.dyn_cast<ModuleMacroInfo*>();
+ if (!Info) {
+ Info = new (PP.getPreprocessorAllocator())
+ ModuleMacroInfo(State.get<MacroDirective *>());
+ State = Info;
+ }
+
+ if (PP.CurSubmoduleState->VisibleModules.getGeneration() !=
+ Info->ActiveModuleMacrosGeneration)
+ PP.updateModuleMacroInfo(II, *Info);
+ return Info;
+ }
+
+ public:
+ MacroState() : MacroState(nullptr) {}
+ MacroState(MacroDirective *MD) : State(MD) {}
+ MacroState(MacroState &&O) LLVM_NOEXCEPT : State(O.State) {
+ O.State = (MacroDirective *)nullptr;
+ }
+ MacroState &operator=(MacroState &&O) LLVM_NOEXCEPT {
+ auto S = O.State;
+ O.State = (MacroDirective *)nullptr;
+ State = S;
+ return *this;
+ }
+ ~MacroState() {
+ if (auto *Info = State.dyn_cast<ModuleMacroInfo*>())
+ Info->~ModuleMacroInfo();
+ }
+
+ MacroDirective *getLatest() const {
+ if (auto *Info = State.dyn_cast<ModuleMacroInfo*>())
+ return Info->MD;
+ return State.get<MacroDirective*>();
+ }
+ void setLatest(MacroDirective *MD) {
+ if (auto *Info = State.dyn_cast<ModuleMacroInfo*>())
+ Info->MD = MD;
+ else
+ State = MD;
+ }
+
+ bool isAmbiguous(Preprocessor &PP, const IdentifierInfo *II) const {
+ auto *Info = getModuleInfo(PP, II);
+ return Info ? Info->IsAmbiguous : false;
+ }
+ ArrayRef<ModuleMacro *>
+ getActiveModuleMacros(Preprocessor &PP, const IdentifierInfo *II) const {
+ if (auto *Info = getModuleInfo(PP, II))
+ return Info->ActiveModuleMacros;
+ return None;
+ }
+
+ MacroDirective::DefInfo findDirectiveAtLoc(SourceLocation Loc,
+ SourceManager &SourceMgr) const {
+ // FIXME: Incorporate module macros into the result of this.
+ return getLatest()->findDirectiveAtLoc(Loc, SourceMgr);
+ }
+
+ void overrideActiveModuleMacros(Preprocessor &PP, IdentifierInfo *II) {
+ if (auto *Info = getModuleInfo(PP, II)) {
+ for (auto *Active : Info->ActiveModuleMacros)
+ Info->OverriddenMacros.push_back(Active);
+ Info->ActiveModuleMacros.clear();
+ Info->IsAmbiguous = false;
+ }
+ }
+ ArrayRef<ModuleMacro*> getOverriddenMacros() const {
+ if (auto *Info = State.dyn_cast<ModuleMacroInfo*>())
+ return Info->OverriddenMacros;
+ return None;
+ }
+ void setOverriddenMacros(Preprocessor &PP,
+ ArrayRef<ModuleMacro *> Overrides) {
+ auto *Info = State.dyn_cast<ModuleMacroInfo*>();
+ if (!Info) {
+ if (Overrides.empty())
+ return;
+ Info = new (PP.getPreprocessorAllocator())
+ ModuleMacroInfo(State.get<MacroDirective *>());
+ State = Info;
+ }
+ Info->OverriddenMacros.clear();
+ Info->OverriddenMacros.insert(Info->OverriddenMacros.end(),
+ Overrides.begin(), Overrides.end());
+ Info->ActiveModuleMacrosGeneration = 0;
+ }
+ };
+
/// For each IdentifierInfo that was associated with a macro, we
/// keep a mapping to the history of all macro definitions and #undefs in
/// the reverse order (the latest one is in the head of the list).
- llvm::DenseMap<const IdentifierInfo*, MacroDirective*> Macros;
+ ///
+ /// This mapping lives within the \p CurSubmoduleState.
+ typedef llvm::DenseMap<const IdentifierInfo *, MacroState> MacroMap;
+
friend class ASTReader;
-
+
+ struct SubmoduleState;
+
+ /// \brief Information about a submodule that we're currently building.
+ struct BuildingSubmoduleInfo {
+ BuildingSubmoduleInfo(Module *M, SourceLocation ImportLoc,
+ SubmoduleState *OuterSubmoduleState)
+ : M(M), ImportLoc(ImportLoc), OuterSubmoduleState(OuterSubmoduleState) {
+ }
+
+ /// The module that we are building.
+ Module *M;
+ /// The location at which the module was included.
+ SourceLocation ImportLoc;
+ /// The previous SubmoduleState.
+ SubmoduleState *OuterSubmoduleState;
+ };
+ SmallVector<BuildingSubmoduleInfo, 8> BuildingSubmoduleStack;
+
+ /// \brief Information about a submodule's preprocessor state.
+ struct SubmoduleState {
+ /// The macros for the submodule.
+ MacroMap Macros;
+ /// The set of modules that are visible within the submodule.
+ VisibleModuleSet VisibleModules;
+ // FIXME: CounterValue?
+ // FIXME: PragmaPushMacroInfo?
+ };
+ std::map<Module*, SubmoduleState> Submodules;
+
+ /// The preprocessor state for preprocessing outside of any submodule.
+ SubmoduleState NullSubmoduleState;
+
+ /// The current submodule state. Will be \p NullSubmoduleState if we're not
+ /// in a submodule.
+ SubmoduleState *CurSubmoduleState;
+
+ /// 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.
///
@@ -427,7 +594,7 @@ class Preprocessor : public RefCountedBase<Preprocessor> {
/// \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
@@ -507,6 +674,7 @@ public:
HeaderSearch &getHeaderSearchInfo() const { return HeaderInfo; }
IdentifierTable &getIdentifierTable() { return Identifiers; }
+ const IdentifierTable &getIdentifierTable() const { return Identifiers; }
SelectorTable &getSelectorTable() { return Selectors; }
Builtin::Context &getBuiltinInfo() { return BuiltinInfo; }
llvm::BumpPtrAllocator &getPreprocessorAllocator() { return BP; }
@@ -601,59 +769,114 @@ public:
}
/// \}
- /// \brief Given an identifier, return its latest MacroDirective if it is
- /// \#defined or null if it isn't \#define'd.
- MacroDirective *getMacroDirective(IdentifierInfo *II) const {
+ bool isMacroDefined(StringRef Id) {
+ return isMacroDefined(&Identifiers.get(Id));
+ }
+ bool isMacroDefined(const IdentifierInfo *II) {
+ return II->hasMacroDefinition() &&
+ (!getLangOpts().Modules || (bool)getMacroDefinition(II));
+ }
+
+ MacroDefinition getMacroDefinition(const IdentifierInfo *II) {
if (!II->hasMacroDefinition())
+ return MacroDefinition();
+
+ MacroState &S = CurSubmoduleState->Macros[II];
+ auto *MD = S.getLatest();
+ while (MD && isa<VisibilityMacroDirective>(MD))
+ MD = MD->getPrevious();
+ return MacroDefinition(dyn_cast_or_null<DefMacroDirective>(MD),
+ S.getActiveModuleMacros(*this, II),
+ S.isAmbiguous(*this, II));
+ }
+
+ MacroDefinition getMacroDefinitionAtLoc(const IdentifierInfo *II,
+ SourceLocation Loc) {
+ if (!II->hadMacroDefinition())
+ return MacroDefinition();
+
+ MacroState &S = CurSubmoduleState->Macros[II];
+ MacroDirective::DefInfo DI;
+ if (auto *MD = S.getLatest())
+ DI = MD->findDirectiveAtLoc(Loc, getSourceManager());
+ // FIXME: Compute the set of active module macros at the specified location.
+ return MacroDefinition(DI.getDirective(),
+ S.getActiveModuleMacros(*this, II),
+ S.isAmbiguous(*this, II));
+ }
+
+ /// \brief Given an identifier, return its latest non-imported MacroDirective
+ /// if it is \#define'd and not \#undef'd, or null if it isn't \#define'd.
+ MacroDirective *getLocalMacroDirective(const IdentifierInfo *II) const {
+ if (!II->hasMacroDefinition())
+ return nullptr;
+
+ auto *MD = getLocalMacroDirectiveHistory(II);
+ if (!MD || MD->getDefinition().isUndefined())
return nullptr;
- MacroDirective *MD = getMacroDirectiveHistory(II);
- assert(MD->isDefined() && "Macro is undefined!");
return MD;
}
- const MacroInfo *getMacroInfo(IdentifierInfo *II) const {
+ const MacroInfo *getMacroInfo(const IdentifierInfo *II) const {
return const_cast<Preprocessor*>(this)->getMacroInfo(II);
}
- MacroInfo *getMacroInfo(IdentifierInfo *II) {
- if (MacroDirective *MD = getMacroDirective(II))
- return MD->getMacroInfo();
+ MacroInfo *getMacroInfo(const IdentifierInfo *II) {
+ if (!II->hasMacroDefinition())
+ return nullptr;
+ if (auto MD = getMacroDefinition(II))
+ return MD.getMacroInfo();
return nullptr;
}
- /// \brief Given an identifier, return the (probably #undef'd) MacroInfo
- /// representing the most recent macro definition.
+ /// \brief Given an identifier, return the latest non-imported macro
+ /// directive for that identifier.
///
- /// One can iterate over all previous macro definitions from the most recent
- /// one. This should only be called for identifiers that hadMacroDefinition().
- MacroDirective *getMacroDirectiveHistory(const IdentifierInfo *II) const;
+ /// One can iterate over all previous macro directives from the most recent
+ /// one.
+ MacroDirective *getLocalMacroDirectiveHistory(const IdentifierInfo *II) const;
/// \brief Add a directive to the macro directive history for this identifier.
void appendMacroDirective(IdentifierInfo *II, MacroDirective *MD);
DefMacroDirective *appendDefMacroDirective(IdentifierInfo *II, MacroInfo *MI,
- SourceLocation Loc,
- unsigned ImportedFromModuleID,
- ArrayRef<unsigned> Overrides) {
- DefMacroDirective *MD =
- AllocateDefMacroDirective(MI, Loc, ImportedFromModuleID, Overrides);
+ SourceLocation Loc) {
+ DefMacroDirective *MD = AllocateDefMacroDirective(MI, Loc);
appendMacroDirective(II, MD);
return MD;
}
- DefMacroDirective *appendDefMacroDirective(IdentifierInfo *II, MacroInfo *MI){
- return appendDefMacroDirective(II, MI, MI->getDefinitionLoc(), 0, None);
+ DefMacroDirective *appendDefMacroDirective(IdentifierInfo *II,
+ MacroInfo *MI) {
+ return appendDefMacroDirective(II, MI, MI->getDefinitionLoc());
}
/// \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(Module *Mod, IdentifierInfo *II, MacroInfo *Macro,
+ ArrayRef<ModuleMacro *> Overrides, bool &IsNew);
+ ModuleMacro *getModuleMacro(Module *Mod, IdentifierInfo *II);
+
+ /// \brief Get the list of leaf (non-overridden) module macros for a name.
+ ArrayRef<ModuleMacro*> getLeafModuleMacros(const IdentifierInfo *II) const {
+ auto I = LeafModuleMacros.find(II);
+ if (I != LeafModuleMacros.end())
+ return I->second;
+ return None;
+ }
+
/// \{
/// Iterators for the macro history table. Currently defined macros have
/// IdentifierInfo::hasMacroDefinition() set and an empty
/// MacroInfo::getUndefLoc() at the head of the list.
- typedef llvm::DenseMap<const IdentifierInfo *,
- MacroDirective*>::const_iterator macro_iterator;
+ typedef MacroMap::const_iterator macro_iterator;
macro_iterator macro_begin(bool IncludeExternalMacros = true) const;
macro_iterator macro_end(bool IncludeExternalMacros = true) const;
+ llvm::iterator_range<macro_iterator>
+ macros(bool IncludeExternalMacros = true) const {
+ return llvm::make_range(macro_begin(IncludeExternalMacros),
+ macro_end(IncludeExternalMacros));
+ }
/// \}
/// \brief Return the name of the macro defined before \p Loc that has
@@ -806,6 +1029,12 @@ public:
void LexAfterModuleImport(Token &Result);
+ void makeModuleVisible(Module *M, SourceLocation Loc);
+
+ SourceLocation getModuleImportLoc(Module *M) const {
+ return CurSubmoduleState->VisibleModules.getImportLoc(M);
+ }
+
/// \brief Lex a string literal, which may be the concatenation of multiple
/// string literals and may even come from macro expansion.
/// \returns true on success, false if a error diagnostic has been generated.
@@ -923,7 +1152,7 @@ public:
/// location of an annotation token.
SourceLocation getLastCachedTokenLocation() const {
assert(CachedLexPos != 0);
- return CachedTokens[CachedLexPos-1].getLocation();
+ return CachedTokens[CachedLexPos-1].getLastLoc();
}
/// \brief Replace the last token with an annotation token.
@@ -1188,6 +1417,7 @@ public:
void DumpToken(const Token &Tok, bool DumpFlags = false) const;
void DumpLocation(SourceLocation Loc) const;
void DumpMacro(const MacroInfo &MI) const;
+ void dumpMacroInfo(const IdentifierInfo *II);
/// \brief Given a location that specifies the start of a
/// token, return a new location that specifies a character within the token.
@@ -1406,17 +1636,19 @@ private:
void PropagateLineStartLeadingSpaceInfo(Token &Result);
+ void EnterSubmodule(Module *M, SourceLocation ImportLoc);
+ void LeaveSubmodule();
+
+ /// Update the set of active module macros and ambiguity flag for a module
+ /// macro name.
+ void updateModuleMacroInfo(const IdentifierInfo *II, ModuleMacroInfo &Info);
+
/// \brief Allocate a new MacroInfo object.
MacroInfo *AllocateMacroInfo();
- DefMacroDirective *
- AllocateDefMacroDirective(MacroInfo *MI, SourceLocation Loc,
- unsigned ImportedFromModuleID = 0,
- ArrayRef<unsigned> Overrides = None);
- UndefMacroDirective *
- AllocateUndefMacroDirective(SourceLocation UndefLoc,
- unsigned ImportedFromModuleID = 0,
- ArrayRef<unsigned> Overrides = None);
+ DefMacroDirective *AllocateDefMacroDirective(MacroInfo *MI,
+ SourceLocation Loc);
+ UndefMacroDirective *AllocateUndefMacroDirective(SourceLocation UndefLoc);
VisibilityMacroDirective *AllocateVisibilityMacroDirective(SourceLocation Loc,
bool isPublic);
@@ -1470,7 +1702,7 @@ private:
/// If an identifier token is read that is to be expanded as a macro, handle
/// it and return the next token as 'Tok'. If we lexed a token, return true;
/// otherwise the caller should lex again.
- bool HandleMacroExpandedIdentifier(Token &Tok, MacroDirective *MD);
+ bool HandleMacroExpandedIdentifier(Token &Tok, const MacroDefinition &MD);
/// \brief Cache macro expanded tokens for TokenLexers.
//
@@ -1572,11 +1804,18 @@ private:
void HandleImportDirective(SourceLocation HashLoc, Token &Tok);
void HandleMicrosoftImportDirective(Token &Tok);
+public:
// Module inclusion testing.
- /// \brief Find the module for the source or header file that \p FilenameLoc
- /// points to.
- Module *getModuleForLocation(SourceLocation FilenameLoc);
+ /// \brief Find the module that owns the source or header file that
+ /// \p Loc points to. If the location is in a file that was included
+ /// into a module, or is outside any module, returns nullptr.
+ Module *getModuleForLocation(SourceLocation Loc);
+ /// \brief Find the module that contains the specified location, either
+ /// directly or indirectly.
+ Module *getModuleContainingLocation(SourceLocation Loc);
+
+private:
// Macro handling.
void HandleDefineDirective(Token &Tok, bool ImmediatelyAfterTopLevelIfndef);
void HandleUndefDirective(Token &Tok);
diff --git a/include/clang/Lex/PreprocessorLexer.h b/include/clang/Lex/PreprocessorLexer.h
index 3a91fa72f2e5..6d6cf05a96c4 100644
--- a/include/clang/Lex/PreprocessorLexer.h
+++ b/include/clang/Lex/PreprocessorLexer.h
@@ -69,8 +69,8 @@ protected:
/// we are currently in.
SmallVector<PPConditionalInfo, 4> ConditionalStack;
- PreprocessorLexer(const PreprocessorLexer &) LLVM_DELETED_FUNCTION;
- void operator=(const PreprocessorLexer &) LLVM_DELETED_FUNCTION;
+ PreprocessorLexer(const PreprocessorLexer &) = delete;
+ void operator=(const PreprocessorLexer &) = delete;
friend class Preprocessor;
PreprocessorLexer(Preprocessor *pp, FileID fid);
diff --git a/include/clang/Lex/Token.h b/include/clang/Lex/Token.h
index 4a53c9c1bb19..e0878093402a 100644
--- a/include/clang/Lex/Token.h
+++ b/include/clang/Lex/Token.h
@@ -35,8 +35,8 @@ class IdentifierInfo;
/// can be represented by a single typename annotation token that carries
/// information about the SourceRange of the tokens and the type object.
class Token {
- /// The location of the token.
- SourceLocation Loc;
+ /// The location of the token. This is actually a SourceLocation.
+ unsigned Loc;
// Conceptually these next two fields could be in a union. However, this
// causes gcc 4.2 to pessimize LexTokenInternal, a very performance critical
@@ -114,13 +114,15 @@ public:
/// \brief Return a source location identifier for the specified
/// offset in the current file.
- SourceLocation getLocation() const { return Loc; }
+ SourceLocation getLocation() const {
+ return SourceLocation::getFromRawEncoding(Loc);
+ }
unsigned getLength() const {
assert(!isAnnotation() && "Annotation tokens have no length field");
return UintData;
}
- void setLocation(SourceLocation L) { Loc = L; }
+ void setLocation(SourceLocation L) { Loc = L.getRawEncoding(); }
void setLength(unsigned Len) {
assert(!isAnnotation() && "Annotation tokens have no length field");
UintData = Len;
@@ -128,7 +130,7 @@ public:
SourceLocation getAnnotationEndLoc() const {
assert(isAnnotation() && "Used AnnotEndLocID on non-annotation token");
- return SourceLocation::getFromRawEncoding(UintData);
+ return SourceLocation::getFromRawEncoding(UintData ? UintData : Loc);
}
void setAnnotationEndLoc(SourceLocation L) {
assert(isAnnotation() && "Used AnnotEndLocID on non-annotation token");
@@ -139,6 +141,11 @@ public:
return isAnnotation() ? getAnnotationEndLoc() : getLocation();
}
+ SourceLocation getEndLoc() const {
+ return isAnnotation() ? getAnnotationEndLoc()
+ : getLocation().getLocWithOffset(getLength());
+ }
+
/// \brief SourceRange of the group of tokens that this annotation token
/// represents.
SourceRange getAnnotationRange() const {
@@ -157,7 +164,7 @@ public:
Flags = 0;
PtrData = nullptr;
UintData = 0;
- Loc = SourceLocation();
+ Loc = SourceLocation().getRawEncoding();
}
IdentifierInfo *getIdentifierInfo() const {
diff --git a/include/clang/Lex/TokenLexer.h b/include/clang/Lex/TokenLexer.h
index 306f98e2609a..31197367c422 100644
--- a/include/clang/Lex/TokenLexer.h
+++ b/include/clang/Lex/TokenLexer.h
@@ -99,8 +99,8 @@ class TokenLexer {
/// should not be subject to further macro expansion.
bool DisableMacroExpansion : 1;
- TokenLexer(const TokenLexer &) LLVM_DELETED_FUNCTION;
- void operator=(const TokenLexer &) LLVM_DELETED_FUNCTION;
+ TokenLexer(const TokenLexer &) = delete;
+ void operator=(const TokenLexer &) = delete;
public:
/// Create a TokenLexer for the specified macro with the specified actual
/// arguments. Note that this ctor takes ownership of the ActualArgs pointer.