aboutsummaryrefslogtreecommitdiff
path: root/include/clang/Lex
diff options
context:
space:
mode:
Diffstat (limited to 'include/clang/Lex')
-rw-r--r--include/clang/Lex/HeaderSearch.h126
-rw-r--r--include/clang/Lex/HeaderSearchOptions.h89
-rw-r--r--include/clang/Lex/Lexer.h127
-rw-r--r--include/clang/Lex/LiteralSupport.h1
-rw-r--r--include/clang/Lex/MacroArgs.h22
-rw-r--r--include/clang/Lex/MacroInfo.h88
-rw-r--r--include/clang/Lex/ModuleLoader.h31
-rw-r--r--include/clang/Lex/ModuleMap.h75
-rw-r--r--include/clang/Lex/MultipleIncludeOpt.h2
-rw-r--r--include/clang/Lex/PPCallbacks.h40
-rw-r--r--include/clang/Lex/PTHLexer.h25
-rw-r--r--include/clang/Lex/PTHManager.h42
-rw-r--r--include/clang/Lex/Pragma.h29
-rw-r--r--include/clang/Lex/PreprocessingRecord.h70
-rw-r--r--include/clang/Lex/Preprocessor.h294
-rw-r--r--include/clang/Lex/PreprocessorLexer.h47
-rw-r--r--include/clang/Lex/PreprocessorOptions.h55
-rw-r--r--include/clang/Lex/TokenLexer.h111
-rw-r--r--include/clang/Lex/VariadicMacroSupport.h226
19 files changed, 1044 insertions, 456 deletions
diff --git a/include/clang/Lex/HeaderSearch.h b/include/clang/Lex/HeaderSearch.h
index 1b7f80c87ff1..6b9dbfcd1e93 100644
--- a/include/clang/Lex/HeaderSearch.h
+++ b/include/clang/Lex/HeaderSearch.h
@@ -1,4 +1,4 @@
-//===--- HeaderSearch.h - Resolve Header File Locations ---------*- C++ -*-===//
+//===- HeaderSearch.h - Resolve Header File Locations -----------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -14,25 +14,37 @@
#ifndef LLVM_CLANG_LEX_HEADERSEARCH_H
#define LLVM_CLANG_LEX_HEADERSEARCH_H
+#include "clang/Basic/SourceLocation.h"
+#include "clang/Basic/SourceManager.h"
#include "clang/Lex/DirectoryLookup.h"
#include "clang/Lex/ModuleMap.h"
#include "llvm/ADT/ArrayRef.h"
-#include "llvm/ADT/IntrusiveRefCntPtr.h"
+#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringSet.h"
+#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Allocator.h"
+#include <cassert>
+#include <cstddef>
#include <memory>
+#include <string>
+#include <utility>
#include <vector>
namespace clang {
-
-class DiagnosticsEngine;
+
+class DiagnosticsEngine;
+class DirectoryEntry;
class ExternalPreprocessorSource;
class FileEntry;
class FileManager;
+class HeaderMap;
class HeaderSearchOptions;
class IdentifierInfo;
+class LangOptions;
+class Module;
class Preprocessor;
+class TargetInfo;
/// \brief The preprocessor keeps track of this information for each
/// file that is \#included.
@@ -76,14 +88,14 @@ struct HeaderFileInfo {
unsigned IsValid : 1;
/// \brief The number of times the file has been included already.
- unsigned short NumIncludes;
+ unsigned short NumIncludes = 0;
/// \brief The ID number of the controlling macro.
///
/// This ID number will be non-zero when there is a controlling
/// macro whose IdentifierInfo may not yet have been loaded from
/// external storage.
- unsigned ControllingMacroID;
+ unsigned ControllingMacroID = 0;
/// If this file has a \#ifndef XXX (or equivalent) guard that
/// protects the entire contents of the file, this is the identifier
@@ -93,17 +105,16 @@ struct HeaderFileInfo {
/// the controlling macro of this header, since
/// getControllingMacro() is able to load a controlling macro from
/// external storage.
- const IdentifierInfo *ControllingMacro;
+ const IdentifierInfo *ControllingMacro = nullptr;
/// \brief If this header came from a framework include, this is the name
/// of the framework.
StringRef Framework;
HeaderFileInfo()
- : isImport(false), isPragmaOnce(false), DirInfo(SrcMgr::C_User),
- External(false), isModuleHeader(false), isCompilingModuleHeader(false),
- Resolved(false), IndexHeaderMapHeader(false), IsValid(0),
- NumIncludes(0), ControllingMacroID(0), ControllingMacro(nullptr) {}
+ : isImport(false), isPragmaOnce(false), DirInfo(SrcMgr::C_User),
+ External(false), isModuleHeader(false), isCompilingModuleHeader(false),
+ Resolved(false), IndexHeaderMapHeader(false), IsValid(false) {}
/// \brief Retrieve the controlling macro for this header file, if
/// any.
@@ -135,6 +146,8 @@ public:
/// \brief Encapsulates the information needed to find the file referenced
/// by a \#include or \#include_next, (sub-)framework lookup, etc.
class HeaderSearch {
+ friend class DirectoryLookup;
+
/// This structure is used to record entries in our framework cache.
struct FrameworkCacheEntry {
/// The directory entry which should be used for the cached framework.
@@ -151,6 +164,7 @@ class HeaderSearch {
DiagnosticsEngine &Diags;
FileManager &FileMgr;
+
/// \#include search path information. Requests for \#include "x" search the
/// directory of the \#including file first, then each directory in SearchDirs
/// consecutively. Requests for <x> search the current dir first, then each
@@ -158,9 +172,9 @@ class HeaderSearch {
/// NoCurDirSearch is true, then the check for the file in the current
/// directory is suppressed.
std::vector<DirectoryLookup> SearchDirs;
- unsigned AngledDirIdx;
- unsigned SystemDirIdx;
- bool NoCurDirSearch;
+ unsigned AngledDirIdx = 0;
+ unsigned SystemDirIdx = 0;
+ bool NoCurDirSearch = false;
/// \brief \#include prefixes for which the 'system header' property is
/// overridden.
@@ -168,7 +182,7 @@ class HeaderSearch {
/// For a \#include "x" or \#include \<x> directive, the last string in this
/// list which is a prefix of 'x' determines whether the file is treated as
/// a system header.
- std::vector<std::pair<std::string, bool> > SystemHeaderPrefixes;
+ std::vector<std::pair<std::string, bool>> SystemHeaderPrefixes;
/// \brief The path to the module cache.
std::string ModuleCachePath;
@@ -182,15 +196,17 @@ class HeaderSearch {
/// Starting index in SearchDirs that the cached search was performed from.
/// If there is a hit and this value doesn't match the current query, the
/// cache has to be ignored.
- unsigned StartIdx;
+ unsigned StartIdx = 0;
+
/// The entry in SearchDirs that satisfied the query.
- unsigned HitIdx;
+ unsigned HitIdx = 0;
+
/// This is non-null if the original filename was mapped to a framework
/// include via a headermap.
- const char *MappedName;
+ const char *MappedName = nullptr;
/// Default constructor -- Initialize all members with zero.
- LookupFileCacheInfo(): StartIdx(0), HitIdx(0), MappedName(nullptr) {}
+ LookupFileCacheInfo() = default;
void reset(unsigned StartIdx) {
this->StartIdx = StartIdx;
@@ -206,13 +222,13 @@ class HeaderSearch {
/// IncludeAliases - maps include file names (including the quotes or
/// angle brackets) to other include file names. This is used to support the
/// include_alias pragma for Microsoft compatibility.
- typedef llvm::StringMap<std::string, llvm::BumpPtrAllocator>
- IncludeAliasMap;
+ using IncludeAliasMap =
+ llvm::StringMap<std::string, llvm::BumpPtrAllocator>;
std::unique_ptr<IncludeAliasMap> IncludeAliases;
/// HeaderMaps - This is a mapping from FileEntry -> HeaderMap, uniquing
/// headermaps. This vector owns the headermap.
- std::vector<std::pair<const FileEntry*, const HeaderMap*> > HeaderMaps;
+ std::vector<std::pair<const FileEntry *, const HeaderMap *>> HeaderMaps;
/// \brief The mapping between modules and headers.
mutable ModuleMap ModMap;
@@ -231,26 +247,23 @@ class HeaderSearch {
/// \brief Entity used to resolve the identifier IDs of controlling
/// macros into IdentifierInfo pointers, and keep the identifire up to date,
/// as needed.
- ExternalPreprocessorSource *ExternalLookup;
+ ExternalPreprocessorSource *ExternalLookup = nullptr;
/// \brief Entity used to look up stored header file information.
- ExternalHeaderFileInfoSource *ExternalSource;
+ ExternalHeaderFileInfoSource *ExternalSource = nullptr;
// Various statistics we track for performance analysis.
- unsigned NumIncluded;
- unsigned NumMultiIncludeFileOptzn;
- unsigned NumFrameworkLookups, NumSubFrameworkLookups;
+ unsigned NumIncluded = 0;
+ unsigned NumMultiIncludeFileOptzn = 0;
+ unsigned NumFrameworkLookups = 0;
+ unsigned NumSubFrameworkLookups = 0;
- // HeaderSearch doesn't support default or copy construction.
- HeaderSearch(const HeaderSearch&) = delete;
- void operator=(const HeaderSearch&) = delete;
-
- friend class DirectoryLookup;
-
public:
HeaderSearch(std::shared_ptr<HeaderSearchOptions> HSOpts,
SourceManager &SourceMgr, DiagnosticsEngine &Diags,
const LangOptions &LangOpts, const TargetInfo *Target);
+ HeaderSearch(const HeaderSearch &) = delete;
+ HeaderSearch &operator=(const HeaderSearch &) = delete;
~HeaderSearch();
/// \brief Retrieve the header-search options with which this header search
@@ -282,7 +295,7 @@ public:
}
/// \brief Set the list of system header prefixes.
- void SetSystemHeaderPrefixes(ArrayRef<std::pair<std::string, bool> > P) {
+ void SetSystemHeaderPrefixes(ArrayRef<std::pair<std::string, bool>> P) {
SystemHeaderPrefixes.assign(P.begin(), P.end());
}
@@ -310,7 +323,7 @@ public:
IncludeAliasMap::const_iterator Iter = IncludeAliases->find(Source);
if (Iter != IncludeAliases->end())
return Iter->second;
- return StringRef();
+ return {};
}
/// \brief Set the path to the module cache.
@@ -471,29 +484,40 @@ public:
/// \brief Get filenames for all registered header maps.
void getHeaderMapFileNames(SmallVectorImpl<std::string> &Names) const;
- /// \brief Retrieve the name of the module file that should be used to
- /// load the given module.
+ /// \brief Retrieve the name of the cached module file that should be used
+ /// to load the given module.
///
/// \param Module The module whose module file name will be returned.
///
/// \returns The name of the module file that corresponds to this module,
/// or an empty string if this module does not correspond to any module file.
- std::string getModuleFileName(Module *Module);
+ std::string getCachedModuleFileName(Module *Module);
+
+ /// \brief Retrieve the name of the prebuilt module file that should be used
+ /// to load a module with the given name.
+ ///
+ /// \param ModuleName The module whose module file name will be returned.
+ ///
+ /// \param FileMapOnly If true, then only look in the explicit module name
+ // to file name map and skip the directory search.
+ ///
+ /// \returns The name of the module file that corresponds to this module,
+ /// or an empty string if this module does not correspond to any module file.
+ std::string getPrebuiltModuleFileName(StringRef ModuleName,
+ bool FileMapOnly = false);
- /// \brief Retrieve the name of the module file that should be used to
- /// load a module with the given name.
+ /// \brief Retrieve the name of the (to-be-)cached module file that should
+ /// be used to load a module with the given name.
///
/// \param ModuleName The module whose module file name will be returned.
///
/// \param ModuleMapPath A path that when combined with \c ModuleName
/// uniquely identifies this module. See Module::ModuleMap.
///
- /// \param UsePrebuiltPath Whether we should use the prebuilt module path.
- ///
/// \returns The name of the module file that corresponds to this module,
/// or an empty string if this module does not correspond to any module file.
- std::string getModuleFileName(StringRef ModuleName, StringRef ModuleMapPath,
- bool UsePrebuiltPath);
+ std::string getCachedModuleFileName(StringRef ModuleName,
+ StringRef ModuleMapPath);
/// \brief Lookup a module Search for a module with the given name.
///
@@ -560,7 +584,6 @@ public:
void loadTopLevelSystemModules();
private:
-
/// \brief Lookup a module with the given module name and search-name.
///
/// \param ModuleName The name of the module we're looking for.
@@ -640,7 +663,8 @@ public:
bool WantExternal = true) const;
// Used by external tools
- typedef std::vector<DirectoryLookup>::const_iterator search_dir_iterator;
+ using search_dir_iterator = std::vector<DirectoryLookup>::const_iterator;
+
search_dir_iterator search_dir_begin() const { return SearchDirs.begin(); }
search_dir_iterator search_dir_end() const { return SearchDirs.end(); }
unsigned search_dir_size() const { return SearchDirs.size(); }
@@ -648,6 +672,7 @@ public:
search_dir_iterator quoted_dir_begin() const {
return SearchDirs.begin();
}
+
search_dir_iterator quoted_dir_end() const {
return SearchDirs.begin() + AngledDirIdx;
}
@@ -655,6 +680,7 @@ public:
search_dir_iterator angled_dir_begin() const {
return SearchDirs.begin() + AngledDirIdx;
}
+
search_dir_iterator angled_dir_end() const {
return SearchDirs.begin() + SystemDirIdx;
}
@@ -662,6 +688,7 @@ public:
search_dir_iterator system_dir_begin() const {
return SearchDirs.begin() + SystemDirIdx;
}
+
search_dir_iterator system_dir_end() const { return SearchDirs.end(); }
/// \brief Retrieve a uniqued framework name.
@@ -684,10 +711,13 @@ private:
enum LoadModuleMapResult {
/// \brief The module map file had already been loaded.
LMM_AlreadyLoaded,
+
/// \brief The module map file was loaded by this invocation.
LMM_NewlyLoaded,
+
/// \brief There is was directory with the given name.
LMM_NoDirectory,
+
/// \brief There was either no module map file or the module map file was
/// invalid.
LMM_InvalidModuleMap
@@ -723,6 +753,6 @@ private:
bool IsSystem, bool IsFramework);
};
-} // end namespace clang
+} // namespace clang
-#endif
+#endif // LLVM_CLANG_LEX_HEADERSEARCH_H
diff --git a/include/clang/Lex/HeaderSearchOptions.h b/include/clang/Lex/HeaderSearchOptions.h
index ca3a84e75e18..937ad9863db3 100644
--- a/include/clang/Lex/HeaderSearchOptions.h
+++ b/include/clang/Lex/HeaderSearchOptions.h
@@ -1,4 +1,4 @@
-//===--- HeaderSearchOptions.h ----------------------------------*- C++ -*-===//
+//===- HeaderSearchOptions.h ------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -12,35 +12,55 @@
#include "clang/Basic/LLVM.h"
#include "llvm/ADT/CachedHashString.h"
-#include "llvm/ADT/IntrusiveRefCntPtr.h"
#include "llvm/ADT/SetVector.h"
#include "llvm/ADT/StringRef.h"
+#include <cstdint>
#include <string>
#include <vector>
+#include <map>
namespace clang {
namespace frontend {
- /// IncludeDirGroup - Identifies the group an include Entry belongs to,
- /// representing its relative positive in the search list.
- /// \#include directives whose paths are enclosed by string quotes ("")
- /// start searching at the Quoted group (specified by '-iquote'),
- /// then search the Angled group, then the System group, etc.
- enum IncludeDirGroup {
- Quoted = 0, ///< '\#include ""' paths, added by 'gcc -iquote'.
- Angled, ///< Paths for '\#include <>' added by '-I'.
- IndexHeaderMap, ///< Like Angled, but marks header maps used when
- /// building frameworks.
- System, ///< Like Angled, but marks system directories.
- ExternCSystem, ///< Like System, but headers are implicitly wrapped in
- /// extern "C".
- CSystem, ///< Like System, but only used for C.
- CXXSystem, ///< Like System, but only used for C++.
- ObjCSystem, ///< Like System, but only used for ObjC.
- ObjCXXSystem, ///< Like System, but only used for ObjC++.
- After ///< Like System, but searched after the system directories.
- };
-}
+
+/// IncludeDirGroup - Identifies the group an include Entry belongs to,
+/// representing its relative positive in the search list.
+/// \#include directives whose paths are enclosed by string quotes ("")
+/// start searching at the Quoted group (specified by '-iquote'),
+/// then search the Angled group, then the System group, etc.
+enum IncludeDirGroup {
+ /// '\#include ""' paths, added by 'gcc -iquote'.
+ Quoted = 0,
+
+ /// Paths for '\#include <>' added by '-I'.
+ Angled,
+
+ /// Like Angled, but marks header maps used when building frameworks.
+ IndexHeaderMap,
+
+ /// Like Angled, but marks system directories.
+ System,
+
+ /// Like System, but headers are implicitly wrapped in extern "C".
+ ExternCSystem,
+
+ /// Like System, but only used for C.
+ CSystem,
+
+ /// Like System, but only used for C++.
+ CXXSystem,
+
+ /// Like System, but only used for ObjC.
+ ObjCSystem,
+
+ /// Like System, but only used for ObjC++.
+ ObjCXXSystem,
+
+ /// Like System, but searched after the system directories.
+ After
+};
+
+} // namespace frontend
/// HeaderSearchOptions - Helper class for storing options related to the
/// initialization of the HeaderSearch object.
@@ -58,8 +78,8 @@ public:
Entry(StringRef path, frontend::IncludeDirGroup group, bool isFramework,
bool ignoreSysRoot)
- : Path(path), Group(group), IsFramework(isFramework),
- IgnoreSysRoot(ignoreSysRoot) {}
+ : Path(path), Group(group), IsFramework(isFramework),
+ IgnoreSysRoot(ignoreSysRoot) {}
};
struct SystemHeaderPrefix {
@@ -71,7 +91,7 @@ public:
bool IsSystemHeader;
SystemHeaderPrefix(StringRef Prefix, bool IsSystemHeader)
- : Prefix(Prefix), IsSystemHeader(IsSystemHeader) {}
+ : Prefix(Prefix), IsSystemHeader(IsSystemHeader) {}
};
/// If non-empty, the directory to use as a "virtual system root" for include
@@ -94,6 +114,9 @@ public:
/// \brief The directory used for a user build.
std::string ModuleUserBuildPath;
+ /// \brief The mapping of module names to prebuilt module files.
+ std::map<std::string, std::string> PrebuiltModuleFiles;
+
/// \brief The directories used to load prebuilt module files.
std::vector<std::string> PrebuiltModulePaths;
@@ -126,7 +149,7 @@ public:
/// files.
///
/// The default value is large, e.g., the operation runs once a week.
- unsigned ModuleCachePruneInterval;
+ unsigned ModuleCachePruneInterval = 7 * 24 * 60 * 60;
/// \brief The time (in seconds) after which an unused module file will be
/// considered unused and will, therefore, be pruned.
@@ -135,13 +158,13 @@ public:
/// accessed in this many seconds will be removed. The default value is
/// large, e.g., a month, to avoid forcing infrequently-used modules to be
/// regenerated often.
- unsigned ModuleCachePruneAfter;
+ unsigned ModuleCachePruneAfter = 31 * 24 * 60 * 60;
/// \brief The time in seconds when the build session started.
///
/// This time is used by other optimizations in header search and module
/// loading.
- uint64_t BuildSessionTimestamp;
+ uint64_t BuildSessionTimestamp = 0;
/// \brief The set of macro names that should be ignored for the purposes
/// of computing the module hash.
@@ -181,10 +204,8 @@ public:
unsigned ModulesHashContent : 1;
HeaderSearchOptions(StringRef _Sysroot = "/")
- : Sysroot(_Sysroot), ModuleFormat("raw"), DisableModuleHash(0),
- ImplicitModuleMaps(0), ModuleMapFileHomeIsCwd(0),
- ModuleCachePruneInterval(7 * 24 * 60 * 60),
- ModuleCachePruneAfter(31 * 24 * 60 * 60), BuildSessionTimestamp(0),
+ : Sysroot(_Sysroot), ModuleFormat("raw"), DisableModuleHash(false),
+ ImplicitModuleMaps(false), ModuleMapFileHomeIsCwd(false),
UseBuiltinIncludes(true), UseStandardSystemIncludes(true),
UseStandardCXXIncludes(true), UseLibcxx(false), Verbose(false),
ModulesValidateOncePerBuildSession(false),
@@ -213,6 +234,6 @@ public:
}
};
-} // end namespace clang
+} // namespace clang
-#endif
+#endif // LLVM_CLANG_LEX_HEADERSEARCHOPTIONS_H
diff --git a/include/clang/Lex/Lexer.h b/include/clang/Lex/Lexer.h
index 3be733167e5c..d58849654cb8 100644
--- a/include/clang/Lex/Lexer.h
+++ b/include/clang/Lex/Lexer.h
@@ -1,4 +1,4 @@
-//===--- Lexer.h - C Language Family Lexer ----------------------*- C++ -*-===//
+//===- Lexer.h - C Language Family Lexer ------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -15,45 +15,88 @@
#define LLVM_CLANG_LEX_LEXER_H
#include "clang/Basic/LangOptions.h"
+#include "clang/Basic/SourceLocation.h"
+#include "clang/Basic/TokenKinds.h"
#include "clang/Lex/PreprocessorLexer.h"
+#include "clang/Lex/Token.h"
+#include "llvm/ADT/Optional.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringRef.h"
#include <cassert>
+#include <cstdint>
#include <string>
+namespace llvm {
+
+class MemoryBuffer;
+
+} // namespace llvm
+
namespace clang {
-class DiagnosticsEngine;
-class SourceManager;
-class Preprocessor;
+
class DiagnosticBuilder;
+class Preprocessor;
+class SourceManager;
/// ConflictMarkerKind - Kinds of conflict marker which the lexer might be
/// recovering from.
enum ConflictMarkerKind {
/// Not within a conflict marker.
CMK_None,
+
/// A normal or diff3 conflict marker, initiated by at least 7 "<"s,
/// separated by at least 7 "="s or "|"s, and terminated by at least 7 ">"s.
CMK_Normal,
+
/// A Perforce-style conflict marker, initiated by 4 ">"s,
/// separated by 4 "="s, and terminated by 4 "<"s.
CMK_Perforce
};
+/// Describes the bounds (start, size) of the preamble and a flag required by
+/// PreprocessorOptions::PrecompiledPreambleBytes.
+/// The preamble includes the BOM, if any.
+struct PreambleBounds {
+ /// \brief Size of the preamble in bytes.
+ unsigned Size;
+
+ /// \brief Whether the preamble ends at the start of a new line.
+ ///
+ /// Used to inform the lexer as to whether it's starting at the beginning of
+ /// a line after skipping the preamble.
+ bool PreambleEndsAtStartOfLine;
+
+ PreambleBounds(unsigned Size, bool PreambleEndsAtStartOfLine)
+ : Size(Size), PreambleEndsAtStartOfLine(PreambleEndsAtStartOfLine) {}
+};
+
/// Lexer - This provides a simple interface that turns a text buffer into a
/// stream of tokens. This provides no support for file reading or buffering,
/// or buffering/seeking of tokens, only forward lexing is supported. It relies
/// on the specified Preprocessor object to handle preprocessor directives, etc.
class Lexer : public PreprocessorLexer {
+ friend class Preprocessor;
+
void anchor() override;
//===--------------------------------------------------------------------===//
// Constant configuration values for this lexer.
- const char *BufferStart; // Start of the buffer.
- const char *BufferEnd; // End of the buffer.
- SourceLocation FileLoc; // Location for start of file.
- LangOptions LangOpts; // LangOpts enabled by this language (cache).
- bool Is_PragmaLexer; // True if lexer for _Pragma handling.
-
+
+ // Start of the buffer.
+ const char *BufferStart;
+
+ // End of the buffer.
+ const char *BufferEnd;
+
+ // Location for start of file.
+ SourceLocation FileLoc;
+
+ // LangOpts enabled by this language (cache).
+ LangOptions LangOpts;
+
+ // True if lexer for _Pragma handling.
+ bool Is_PragmaLexer;
+
//===--------------------------------------------------------------------===//
// Context-specific lexing flags set by the preprocessor.
//
@@ -89,13 +132,9 @@ class Lexer : public PreprocessorLexer {
// CurrentConflictMarkerState - The kind of conflict marker we are handling.
ConflictMarkerKind CurrentConflictMarkerState;
- Lexer(const Lexer &) = delete;
- void operator=(const Lexer &) = delete;
- friend class Preprocessor;
-
void InitLexer(const char *BufStart, const char *BufPtr, const char *BufEnd);
-public:
+public:
/// Lexer constructor - Create a new lexer object for the specified buffer
/// with the specified preprocessor managing the lexing process. This lexer
/// assumes that the associated file buffer and Preprocessor objects will
@@ -114,6 +153,9 @@ public:
Lexer(FileID FID, const llvm::MemoryBuffer *InputBuffer,
const SourceManager &SM, const LangOptions &LangOpts);
+ Lexer(const Lexer &) = delete;
+ Lexer &operator=(const Lexer &) = delete;
+
/// Create_PragmaLexer: Lexer constructor - Create a new lexer object for
/// _Pragma expansion. This has a variety of magic semantics that this method
/// sets up. It returns a new'd Lexer that must be delete'd when done.
@@ -122,7 +164,6 @@ public:
SourceLocation ExpansionLocEnd,
unsigned TokLen, Preprocessor &PP);
-
/// getLangOpts - Return the language features currently enabled.
/// NOTE: this lexer modifies features as a file is parsed!
const LangOptions &getLangOpts() const { return LangOpts; }
@@ -224,17 +265,16 @@ public:
/// \brief Return the current location in the buffer.
const char *getBufferLocation() const { return BufferPtr; }
-
- /// Stringify - Convert the specified string into a C string by escaping '\'
- /// and " characters. This does not add surrounding ""'s to the string.
+
+ /// Stringify - Convert the specified string into a C string by i) escaping
+ /// '\\' and " characters and ii) replacing newline character(s) with "\\n".
/// If Charify is true, this escapes the ' character instead of ".
static std::string Stringify(StringRef Str, bool Charify = false);
- /// Stringify - Convert the specified string into a C string by escaping '\'
- /// and " characters. This does not add surrounding ""'s to the string.
+ /// Stringify - Convert the specified string into a C string by i) escaping
+ /// '\\' and " characters and ii) replacing newline character(s) with "\\n".
static void Stringify(SmallVectorImpl<char> &Str);
-
/// getSpelling - This method is used to get the spelling of a token into a
/// preallocated buffer, instead of as an std::string. The caller is required
/// to allocate enough space for the token, which is guaranteed to be at least
@@ -245,11 +285,11 @@ public:
/// to point to a constant buffer with the data already in it (avoiding a
/// copy). The caller is not allowed to modify the returned buffer pointer
/// if an internal buffer is returned.
- static unsigned getSpelling(const Token &Tok, const char *&Buffer,
+ static unsigned getSpelling(const Token &Tok, const char *&Buffer,
const SourceManager &SourceMgr,
const LangOptions &LangOpts,
bool *Invalid = nullptr);
-
+
/// getSpelling() - Return the 'spelling' of the Tok token. The spelling of a
/// token is the characters used to represent the token in the source file
/// after trigraph expansion and escaped-newline folding. In particular, this
@@ -257,7 +297,7 @@ public:
/// UCNs, etc.
static std::string getSpelling(const Token &Tok,
const SourceManager &SourceMgr,
- const LangOptions &LangOpts,
+ const LangOptions &LangOpts,
bool *Invalid = nullptr);
/// getSpelling - This method is used to get the spelling of the
@@ -273,7 +313,7 @@ public:
const SourceManager &SourceMgr,
const LangOptions &LangOpts,
bool *invalid = nullptr);
-
+
/// MeasureTokenLength - Relex the token at the specified location and return
/// its length in bytes in the input file. If the token needs cleaning (e.g.
/// includes a trigraph or an escaped newline) then this count includes bytes
@@ -295,7 +335,7 @@ public:
static SourceLocation GetBeginningOfToken(SourceLocation Loc,
const SourceManager &SM,
const LangOptions &LangOpts);
-
+
/// AdvanceToTokenCharacter - If the current SourceLocation specifies a
/// location at the start of a token, return a new location that specifies a
/// character within the token. This handles trigraphs and escaped newlines.
@@ -303,7 +343,7 @@ public:
unsigned Character,
const SourceManager &SM,
const LangOptions &LangOpts);
-
+
/// \brief Computes the source location just past the end of the
/// token at this source location.
///
@@ -443,11 +483,18 @@ public:
/// to fewer than this number of lines.
///
/// \returns The offset into the file where the preamble ends and the rest
- /// of the file begins along with a boolean value indicating whether
+ /// of the file begins along with a boolean value indicating whether
/// the preamble ends at the beginning of a new line.
- static std::pair<unsigned, bool> ComputePreamble(StringRef Buffer,
- const LangOptions &LangOpts,
- unsigned MaxLines = 0);
+ static PreambleBounds ComputePreamble(StringRef Buffer,
+ const LangOptions &LangOpts,
+ unsigned MaxLines = 0);
+
+ /// Finds the token that comes right after the given location.
+ ///
+ /// Returns the next token, or none if the location is inside a macro.
+ static Optional<Token> findNextToken(SourceLocation Loc,
+ const SourceManager &SM,
+ const LangOptions &LangOpts);
/// \brief Checks that the given token is the first token that occurs after
/// the given location (this excludes comments and whitespace). Returns the
@@ -463,6 +510,10 @@ public:
/// \brief Returns true if the given character could appear in an identifier.
static bool isIdentifierBodyChar(char c, const LangOptions &LangOpts);
+ /// \brief Checks whether new line pointed by Str is preceded by escape
+ /// sequence.
+ static bool isNewLineEscaped(const char *BufferStart, const char *Str);
+
/// getCharAndSizeNoWarn - Like the getCharAndSize method, but does not ever
/// emit a warning.
static inline char getCharAndSizeNoWarn(const char *Ptr, unsigned &Size,
@@ -483,9 +534,9 @@ public:
static StringRef getIndentationForLine(SourceLocation Loc,
const SourceManager &SM);
+private:
//===--------------------------------------------------------------------===//
// Internal implementation interfaces.
-private:
/// LexTokenInternal - Internal interface to lex a preprocessing token. Called
/// by Lex.
@@ -614,7 +665,7 @@ private:
//===--------------------------------------------------------------------===//
// Other lexer functions.
- void SkipBytes(unsigned Bytes, bool StartOfLine);
+ void SetByteOffset(unsigned Offset, bool StartOfLine);
void PropagateLineStartLeadingSpaceInfo(Token &Result);
@@ -639,7 +690,7 @@ private:
bool SkipBlockComment (Token &Result, const char *CurPtr,
bool &TokAtPhysicalStartOfLine);
bool SaveLineComment (Token &Result, const char *CurPtr);
-
+
bool IsStartOfConflictMarker(const char *CurPtr);
bool HandleEndOfConflictMarker(const char *CurPtr);
@@ -658,7 +709,7 @@ private:
/// valid), this parameter will be updated to point to the
/// character after the UCN.
/// \param SlashLoc The position in the source buffer of the '\'.
- /// \param Tok The token being formed. Pass \c NULL to suppress diagnostics
+ /// \param Tok The token being formed. Pass \c nullptr to suppress diagnostics
/// and handle token formation in the caller.
///
/// \return The Unicode codepoint specified by the UCN, or 0 if the UCN is
@@ -687,6 +738,6 @@ private:
bool tryConsumeIdentifierUTF8Char(const char *&CurPtr);
};
-} // end namespace clang
+} // namespace clang
-#endif
+#endif // LLVM_CLANG_LEX_LEXER_H
diff --git a/include/clang/Lex/LiteralSupport.h b/include/clang/Lex/LiteralSupport.h
index b66581b428b1..cc9223eb7dbb 100644
--- a/include/clang/Lex/LiteralSupport.h
+++ b/include/clang/Lex/LiteralSupport.h
@@ -65,6 +65,7 @@ public:
bool isHalf : 1; // 1.0h
bool isFloat : 1; // 1.0f
bool isImaginary : 1; // 1.0i
+ bool isFloat16 : 1; // 1.0f16
bool isFloat128 : 1; // 1.0q
uint8_t MicrosoftInteger; // Microsoft suffix extension i8, i16, i32, or i64.
diff --git a/include/clang/Lex/MacroArgs.h b/include/clang/Lex/MacroArgs.h
index cfe46ceb0979..a202550da3b3 100644
--- a/include/clang/Lex/MacroArgs.h
+++ b/include/clang/Lex/MacroArgs.h
@@ -17,6 +17,7 @@
#include "clang/Basic/LLVM.h"
#include "clang/Lex/Token.h"
#include "llvm/ADT/ArrayRef.h"
+#include "llvm/Support/TrailingObjects.h"
#include <vector>
namespace clang {
@@ -26,7 +27,10 @@ namespace clang {
/// MacroArgs - An instance of this class captures information about
/// the formal arguments specified to a function-like macro invocation.
-class MacroArgs {
+class MacroArgs final
+ : private llvm::TrailingObjects<MacroArgs, Token> {
+
+ friend TrailingObjects;
/// NumUnexpArgTokens - The number of raw, unexpanded tokens for the
/// arguments. All of the actual argument tokens are allocated immediately
/// after the MacroArgs object in memory. This is all of the arguments
@@ -89,7 +93,7 @@ public:
/// getPreExpArgument - Return the pre-expanded form of the specified
/// argument.
const std::vector<Token> &
- getPreExpArgument(unsigned Arg, const MacroInfo *MI, Preprocessor &PP);
+ getPreExpArgument(unsigned Arg, Preprocessor &PP);
/// getStringifiedArgument - Compute, cache, and return the specified argument
/// that has been 'stringified' as required by the # operator.
@@ -108,6 +112,20 @@ public:
/// argument, this returns false.
bool isVarargsElidedUse() const { return VarargsElided; }
+ /// Returns true if the macro was defined with a variadic (ellipsis) parameter
+ /// AND was invoked with at least one token supplied as a variadic argument.
+ ///
+ /// \code
+ /// #define F(a) a
+ /// #define V(a, ...) __VA_OPT__(a)
+ /// F() <-- returns false on this invocation.
+ /// V(,a) <-- returns true on this invocation.
+ /// V(,) <-- returns false on this invocation.
+ /// \endcode
+ ///
+
+ bool invokedWithVariadicArgument(const MacroInfo *const MI) const;
+
/// StringifyArgument - Implement C99 6.10.3.2p2, converting a sequence of
/// tokens into the literal string token that should be produced by the C #
/// preprocessor operator. If Charify is true, then it should be turned into
diff --git a/include/clang/Lex/MacroInfo.h b/include/clang/Lex/MacroInfo.h
index d25431b55fdc..3029294209ec 100644
--- a/include/clang/Lex/MacroInfo.h
+++ b/include/clang/Lex/MacroInfo.h
@@ -1,4 +1,4 @@
-//===--- MacroInfo.h - Information about #defined identifiers ---*- C++ -*-===//
+//===- MacroInfo.h - Information about #defined identifiers -----*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -6,27 +6,33 @@
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
-///
+//
/// \file
/// \brief Defines the clang::MacroInfo and clang::MacroDirective classes.
-///
+//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_LEX_MACROINFO_H
#define LLVM_CLANG_LEX_MACROINFO_H
#include "clang/Lex/Token.h"
+#include "clang/Basic/LLVM.h"
+#include "clang/Basic/SourceLocation.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 <algorithm>
#include <cassert>
namespace clang {
+
+class DefMacroDirective;
+class IdentifierInfo;
class Module;
-class ModuleMacro;
class Preprocessor;
+class SourceManager;
/// \brief Encapsulates the data about a macro definition (e.g. its tokens).
///
@@ -37,6 +43,7 @@ class MacroInfo {
/// \brief The location the macro is defined.
SourceLocation Location;
+
/// \brief The location of the last token in the macro.
SourceLocation EndLocation;
@@ -46,10 +53,10 @@ class MacroInfo {
///
/// This can be empty, for, e.g. "#define X()". In a C99-style variadic
/// macro, this includes the \c __VA_ARGS__ identifier on the list.
- IdentifierInfo **ParameterList;
+ IdentifierInfo **ParameterList = nullptr;
/// \see ParameterList
- unsigned NumParameters;
+ unsigned NumParameters = 0;
/// \brief This is the list of tokens that the macro is defined to.
SmallVector<Token, 8> ReplacementTokens;
@@ -169,7 +176,7 @@ public:
/// Parameters - The list of parameters for a function-like macro. This can
/// be empty, for, e.g. "#define X()".
- typedef IdentifierInfo *const *param_iterator;
+ using param_iterator = IdentifierInfo *const *;
bool param_empty() const { return NumParameters == 0; }
param_iterator param_begin() const { return ParameterList; }
param_iterator param_end() const { return ParameterList + NumParameters; }
@@ -224,7 +231,6 @@ public:
bool isWarnIfUnused() const { return IsWarnIfUnused; }
/// \brief Return the number of tokens that this macro expands to.
- ///
unsigned getNumTokens() const { return ReplacementTokens.size(); }
const Token &getReplacementToken(unsigned Tok) const {
@@ -232,7 +238,8 @@ public:
return ReplacementTokens[Tok];
}
- typedef SmallVectorImpl<Token>::const_iterator tokens_iterator;
+ using tokens_iterator = SmallVectorImpl<Token>::const_iterator;
+
tokens_iterator tokens_begin() const { return ReplacementTokens.begin(); }
tokens_iterator tokens_end() const { return ReplacementTokens.end(); }
bool tokens_empty() const { return ReplacementTokens.empty(); }
@@ -269,12 +276,10 @@ public:
void dump() const;
private:
- unsigned getDefinitionLengthSlow(const SourceManager &SM) const;
-
friend class Preprocessor;
-};
-class DefMacroDirective;
+ unsigned getDefinitionLengthSlow(const SourceManager &SM) const;
+};
/// \brief Encapsulates changes to the "macros namespace" (the location where
/// the macro name became active, the location where it was undefined, etc.).
@@ -285,11 +290,15 @@ class DefMacroDirective;
/// create additional DefMacroDirectives for the same MacroInfo.
class MacroDirective {
public:
- enum Kind { MD_Define, MD_Undefine, MD_Visibility };
+ enum Kind {
+ MD_Define,
+ MD_Undefine,
+ MD_Visibility
+ };
protected:
- /// \brief Previous macro directive for the same identifier, or NULL.
- MacroDirective *Previous;
+ /// \brief Previous macro directive for the same identifier, or nullptr.
+ MacroDirective *Previous = nullptr;
SourceLocation Loc;
@@ -306,8 +315,7 @@ protected:
unsigned IsPublic : 1;
MacroDirective(Kind K, SourceLocation Loc)
- : Previous(nullptr), Loc(Loc), MDKind(K), IsFromPCH(false),
- IsPublic(true) {}
+ : Loc(Loc), MDKind(K), IsFromPCH(false), IsPublic(true) {}
public:
Kind getKind() const { return Kind(MDKind); }
@@ -329,13 +337,12 @@ public:
void setIsFromPCH() { IsFromPCH = true; }
class DefInfo {
- DefMacroDirective *DefDirective;
+ DefMacroDirective *DefDirective = nullptr;
SourceLocation UndefLoc;
- bool IsPublic;
+ bool IsPublic = true;
public:
- DefInfo() : DefDirective(nullptr), IsPublic(true) {}
-
+ DefInfo() = default;
DefInfo(DefMacroDirective *DefDirective, SourceLocation UndefLoc,
bool isPublic)
: DefDirective(DefDirective), UndefLoc(UndefLoc), IsPublic(isPublic) {}
@@ -345,6 +352,7 @@ public:
inline SourceLocation getLocation() const;
inline MacroInfo *getMacroInfo();
+
const MacroInfo *getMacroInfo() const {
return const_cast<DefInfo *>(this)->getMacroInfo();
}
@@ -360,6 +368,7 @@ public:
explicit operator bool() const { return isValid(); }
inline DefInfo getPreviousDefinition();
+
const DefInfo getPreviousDefinition() const {
return const_cast<DefInfo *>(this)->getPreviousDefinition();
}
@@ -412,6 +421,7 @@ public:
static bool classof(const MacroDirective *MD) {
return MD->getKind() == MD_Define;
}
+
static bool classof(const DefMacroDirective *) { return true; }
};
@@ -426,6 +436,7 @@ public:
static bool classof(const MacroDirective *MD) {
return MD->getKind() == MD_Undefine;
}
+
static bool classof(const UndefMacroDirective *) { return true; }
};
@@ -444,12 +455,13 @@ public:
static bool classof(const MacroDirective *MD) {
return MD->getKind() == MD_Visibility;
}
+
static bool classof(const VisibilityMacroDirective *) { return true; }
};
inline SourceLocation MacroDirective::DefInfo::getLocation() const {
if (isInvalid())
- return SourceLocation();
+ return {};
return DefDirective->getLocation();
}
@@ -462,7 +474,7 @@ inline MacroInfo *MacroDirective::DefInfo::getMacroInfo() {
inline MacroDirective::DefInfo
MacroDirective::DefInfo::getPreviousDefinition() {
if (isInvalid() || DefDirective->getPrevious() == nullptr)
- return DefInfo();
+ return {};
return DefDirective->getPrevious()->getDefinition();
}
@@ -474,23 +486,26 @@ MacroDirective::DefInfo::getPreviousDefinition() {
///
/// These are stored in a FoldingSet in the preprocessor.
class ModuleMacro : public llvm::FoldingSetNode {
+ friend class Preprocessor;
+
/// 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;
+ unsigned NumOverriddenBy = 0;
+
/// 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),
+ : II(II), Macro(Macro), OwningModule(OwningModule),
NumOverrides(Overrides.size()) {
std::copy(Overrides.begin(), Overrides.end(),
reinterpret_cast<ModuleMacro **>(this + 1));
@@ -504,12 +519,16 @@ public:
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 name of the macro.
+ IdentifierInfo *getName() const { return II; }
+
/// Get the ID of the module that exports this macro.
Module *getOwningModule() const { return OwningModule; }
@@ -519,13 +538,16 @@ public:
/// Iterators over the overridden module IDs.
/// \{
- typedef ModuleMacro *const *overrides_iterator;
+ using overrides_iterator = ModuleMacro *const *;
+
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());
}
@@ -544,7 +566,7 @@ class MacroDefinition {
ArrayRef<ModuleMacro *> ModuleMacros;
public:
- MacroDefinition() : LatestLocalAndAmbiguous(), ModuleMacros() {}
+ MacroDefinition() = default;
MacroDefinition(DefMacroDirective *MD, ArrayRef<ModuleMacro *> MMs,
bool IsAmbiguous)
: LatestLocalAndAmbiguous(MD, IsAmbiguous), ModuleMacros(MMs) {}
@@ -583,6 +605,6 @@ public:
}
};
-} // end namespace clang
+} // namespace clang
-#endif
+#endif // LLVM_CLANG_LEX_MACROINFO_H
diff --git a/include/clang/Lex/ModuleLoader.h b/include/clang/Lex/ModuleLoader.h
index ee0638b57f87..30ea583b71e0 100644
--- a/include/clang/Lex/ModuleLoader.h
+++ b/include/clang/Lex/ModuleLoader.h
@@ -1,4 +1,4 @@
-//===--- ModuleLoader.h - Module Loader Interface ---------------*- C++ -*-===//
+//===- ModuleLoader.h - Module Loader Interface -----------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -11,23 +11,26 @@
// loading named modules.
//
//===----------------------------------------------------------------------===//
+
#ifndef LLVM_CLANG_LEX_MODULELOADER_H
#define LLVM_CLANG_LEX_MODULELOADER_H
+#include "clang/Basic/LLVM.h"
#include "clang/Basic/Module.h"
#include "clang/Basic/SourceLocation.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/PointerIntPair.h"
+#include "llvm/ADT/StringRef.h"
+#include <utility>
namespace clang {
class GlobalModuleIndex;
class IdentifierInfo;
-class Module;
/// \brief A sequence of identifier/location pairs used to describe a particular
/// module or submodule, e.g., std.vector.
-typedef ArrayRef<std::pair<IdentifierInfo *, SourceLocation> > ModuleIdPath;
+using ModuleIdPath = ArrayRef<std::pair<IdentifierInfo *, SourceLocation>>;
/// \brief Describes the result of attempting to load a module.
class ModuleLoadResult {
@@ -35,16 +38,18 @@ public:
enum LoadResultKind {
// We either succeeded or failed to load the named module.
Normal,
+
// The module exists, but does not actually contain the named submodule.
// This should only happen if the named submodule was inferred from an
// umbrella directory, but not actually part of the umbrella header.
MissingExpected,
+
// The module exists but cannot be imported due to a configuration mismatch.
ConfigMismatch
};
llvm::PointerIntPair<Module *, 2, LoadResultKind> Storage;
- ModuleLoadResult() : Storage() { }
+ ModuleLoadResult() = default;
ModuleLoadResult(Module *M) : Storage(M, Normal) {}
ModuleLoadResult(LoadResultKind Kind) : Storage(nullptr, Kind) {}
@@ -69,10 +74,10 @@ public:
class ModuleLoader {
// Building a module if true.
bool BuildingModule;
+
public:
- explicit ModuleLoader(bool BuildingModule = false) :
- BuildingModule(BuildingModule),
- HadFatalFailure(false) {}
+ explicit ModuleLoader(bool BuildingModule = false)
+ : BuildingModule(BuildingModule) {}
virtual ~ModuleLoader();
@@ -80,6 +85,7 @@ public:
bool buildingModule() const {
return BuildingModule;
}
+
/// \brief Flag indicating whether this instance is building a module.
void setBuildingModule(bool BuildingModuleFlag) {
BuildingModule = BuildingModuleFlag;
@@ -144,7 +150,7 @@ public:
virtual bool lookupMissingImports(StringRef Name,
SourceLocation TriggerLoc) = 0;
- bool HadFatalFailure;
+ bool HadFatalFailure = false;
};
/// A module loader that doesn't know how to load modules.
@@ -153,7 +159,7 @@ public:
ModuleLoadResult loadModule(SourceLocation ImportLoc, ModuleIdPath Path,
Module::NameVisibilityKind Visibility,
bool IsInclusionDirective) override {
- return ModuleLoadResult();
+ return {};
}
void loadModuleFromSource(SourceLocation ImportLoc, StringRef ModuleName,
@@ -165,12 +171,13 @@ public:
GlobalModuleIndex *loadGlobalModuleIndex(SourceLocation TriggerLoc) override {
return nullptr;
}
+
bool lookupMissingImports(StringRef Name,
SourceLocation TriggerLoc) override {
- return 0;
+ return false;
}
};
-}
+} // namespace clang
-#endif
+#endif // LLVM_CLANG_LEX_MODULELOADER_H
diff --git a/include/clang/Lex/ModuleMap.h b/include/clang/Lex/ModuleMap.h
index 11506939f9b1..41ed8e49b6c1 100644
--- a/include/clang/Lex/ModuleMap.h
+++ b/include/clang/Lex/ModuleMap.h
@@ -1,4 +1,4 @@
-//===--- ModuleMap.h - Describe the layout of modules -----------*- C++ -*-===//
+//===- ModuleMap.h - Describe the layout of modules -------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -18,7 +18,6 @@
#include "clang/Basic/LangOptions.h"
#include "clang/Basic/Module.h"
#include "clang/Basic/SourceLocation.h"
-#include "clang/Basic/SourceManager.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/PointerIntPair.h"
@@ -28,20 +27,19 @@
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/TinyPtrVector.h"
#include "llvm/ADT/Twine.h"
-#include <algorithm>
+#include <ctime>
#include <memory>
#include <string>
#include <utility>
namespace clang {
+class DiagnosticsEngine;
class DirectoryEntry;
class FileEntry;
class FileManager;
-class DiagnosticConsumer;
-class DiagnosticsEngine;
class HeaderSearch;
-class ModuleMapParser;
+class SourceManager;
/// \brief A mechanism to observe the actions of the module map parser as it
/// reads module map files.
@@ -82,33 +80,40 @@ class ModuleMap {
/// \brief The directory used for Clang-supplied, builtin include headers,
/// such as "stdint.h".
- const DirectoryEntry *BuiltinIncludeDir;
+ const DirectoryEntry *BuiltinIncludeDir = nullptr;
/// \brief Language options used to parse the module map itself.
///
/// These are always simple C language options.
LangOptions MMapLangOpts;
- // The module that the main source file is associated with (the module
- // named LangOpts::CurrentModule, if we've loaded it).
- Module *SourceModule;
+ /// The module that the main source file is associated with (the module
+ /// named LangOpts::CurrentModule, if we've loaded it).
+ Module *SourceModule = nullptr;
+
+ /// The global module for the current TU, if we still own it. (Ownership is
+ /// transferred if/when we create an enclosing module.
+ std::unique_ptr<Module> PendingGlobalModule;
/// \brief The top-level modules that are known.
llvm::StringMap<Module *> Modules;
/// \brief The number of modules we have created in total.
- unsigned NumCreatedModules;
+ unsigned NumCreatedModules = 0;
public:
/// \brief Flags describing the role of a module header.
enum ModuleHeaderRole {
/// \brief This header is normally included in the module.
NormalHeader = 0x0,
+
/// \brief This header is included but private.
PrivateHeader = 0x1,
+
/// \brief This header is part of the module (for layering purposes) but
/// should be textually included.
TextualHeader = 0x2,
+
// Caution: Adding an enumerator needs other changes.
// Adjust the number of bits for KnownHeader::Storage.
// Adjust the bitfield HeaderFileInfo::HeaderRole size.
@@ -119,6 +124,7 @@ public:
/// Convert a header kind to a role. Requires Kind to not be HK_Excluded.
static ModuleHeaderRole headerKindToRole(Module::HeaderKind Kind);
+
/// Convert a header role to a kind.
static Module::HeaderKind headerRoleToKind(ModuleHeaderRole Role);
@@ -128,8 +134,8 @@ public:
llvm::PointerIntPair<Module *, 2, ModuleHeaderRole> Storage;
public:
- KnownHeader() : Storage(nullptr, NormalHeader) { }
- KnownHeader(Module *M, ModuleHeaderRole Role) : Storage(M, Role) { }
+ KnownHeader() : Storage(nullptr, NormalHeader) {}
+ KnownHeader(Module *M, ModuleHeaderRole Role) : Storage(M, Role) {}
friend bool operator==(const KnownHeader &A, const KnownHeader &B) {
return A.Storage == B.Storage;
@@ -162,11 +168,13 @@ public:
}
};
- typedef llvm::SmallPtrSet<const FileEntry *, 1> AdditionalModMapsSet;
+ using AdditionalModMapsSet = llvm::SmallPtrSet<const FileEntry *, 1>;
private:
- typedef llvm::DenseMap<const FileEntry *, SmallVector<KnownHeader, 1>>
- HeadersMap;
+ friend class ModuleMapParser;
+
+ using HeadersMap =
+ llvm::DenseMap<const FileEntry *, SmallVector<KnownHeader, 1>>;
/// \brief Mapping from each header to the module that owns the contents of
/// that header.
@@ -174,6 +182,7 @@ private:
/// Map from file sizes to modules with lazy header directives of that size.
mutable llvm::DenseMap<off_t, llvm::TinyPtrVector<Module*>> LazyHeadersBySize;
+
/// Map from mtimes to modules with lazy header directives with those mtimes.
mutable llvm::DenseMap<time_t, llvm::TinyPtrVector<Module*>>
LazyHeadersByModTime;
@@ -188,9 +197,6 @@ private:
/// \brief The set of attributes that can be attached to a module.
struct Attributes {
- Attributes()
- : IsSystem(), IsExternC(), IsExhaustive(), NoUndeclaredIncludes() {}
-
/// \brief Whether this is a system module.
unsigned IsSystem : 1;
@@ -203,12 +209,14 @@ private:
/// \brief Whether files in this module can only include non-modular headers
/// and headers from used modules.
unsigned NoUndeclaredIncludes : 1;
+
+ Attributes()
+ : IsSystem(false), IsExternC(false), IsExhaustive(false),
+ NoUndeclaredIncludes(false) {}
};
/// \brief A directory for which framework modules can be inferred.
struct InferredDirectory {
- InferredDirectory() : InferModules() {}
-
/// \brief Whether to infer modules from this directory.
unsigned InferModules : 1;
@@ -222,6 +230,8 @@ private:
/// \brief The names of modules that cannot be inferred within this
/// directory.
SmallVector<std::string, 2> ExcludedModules;
+
+ InferredDirectory() : InferModules(false) {}
};
/// \brief A mapping from directories to information about inferring
@@ -238,8 +248,6 @@ private:
/// map.
llvm::DenseMap<const FileEntry *, bool> ParsedModuleMap;
- friend class ModuleMapParser;
-
/// \brief Resolve the given export declaration into an actual export
/// declaration.
///
@@ -341,7 +349,6 @@ public:
HeaderSearch &HeaderInfo);
/// \brief Destroy the module map.
- ///
~ModuleMap();
/// \brief Set the target information.
@@ -460,7 +467,7 @@ public:
/// \param Name The name of the module to find or create.
///
/// \param Parent The module that will act as the parent of this submodule,
- /// or NULL to indicate that this is a top-level module.
+ /// or nullptr to indicate that this is a top-level module.
///
/// \param IsFramework Whether this is a framework module.
///
@@ -472,6 +479,14 @@ public:
bool IsFramework,
bool IsExplicit);
+ /// \brief Create a 'global module' for a C++ Modules TS module interface
+ /// unit.
+ ///
+ /// We model the global module as a submodule of the module interface unit.
+ /// Unfortunately, we can't create the module interface unit's Module until
+ /// later, because we don't know what it will be called.
+ Module *createGlobalModuleForInterfaceUnit(SourceLocation Loc);
+
/// \brief Create a new module for a C++ Modules TS module interface unit.
/// The module must not already exist, and will be configured for the current
/// compilation.
@@ -479,7 +494,8 @@ public:
/// Note that this also sets the current module to the newly-created module.
///
/// \returns The newly-created module.
- Module *createModuleForInterfaceUnit(SourceLocation Loc, StringRef Name);
+ Module *createModuleForInterfaceUnit(SourceLocation Loc, StringRef Name,
+ Module *GlobalModule);
/// \brief Infer the contents of a framework module map from the given
/// framework directory.
@@ -492,7 +508,7 @@ public:
/// \param Module The module whose module map file will be returned, if known.
///
/// \returns The file entry for the module map file containing the given
- /// module, or NULL if the module definition was inferred.
+ /// module, or nullptr if the module definition was inferred.
const FileEntry *getContainingModuleMapFile(const Module *Module) const;
/// \brief Get the module map file that (along with the module name) uniquely
@@ -599,11 +615,12 @@ public:
/// \brief Dump the contents of the module map, for debugging purposes.
void dump();
- typedef llvm::StringMap<Module *>::const_iterator module_iterator;
+ using module_iterator = llvm::StringMap<Module *>::const_iterator;
+
module_iterator module_begin() const { return Modules.begin(); }
module_iterator module_end() const { return Modules.end(); }
};
-} // end namespace clang
+} // namespace clang
#endif // LLVM_CLANG_LEX_MODULEMAP_H
diff --git a/include/clang/Lex/MultipleIncludeOpt.h b/include/clang/Lex/MultipleIncludeOpt.h
index 83e6f99078df..3967f8688966 100644
--- a/include/clang/Lex/MultipleIncludeOpt.h
+++ b/include/clang/Lex/MultipleIncludeOpt.h
@@ -92,7 +92,7 @@ public:
TheMacro = nullptr;
}
- /// getHasReadAnyTokensVal - This is used for the \#ifndef hande-shake at the
+ /// getHasReadAnyTokensVal - This is used for the \#ifndef handshake at the
/// top of the file when reading preprocessor directives. Otherwise, reading
/// the "ifndef x" would count as reading tokens.
bool getHasReadAnyTokensVal() const { return ReadAnyTokens; }
diff --git a/include/clang/Lex/PPCallbacks.h b/include/clang/Lex/PPCallbacks.h
index 81c3bd7d14ec..19bce4dd32e8 100644
--- a/include/clang/Lex/PPCallbacks.h
+++ b/include/clang/Lex/PPCallbacks.h
@@ -235,6 +235,14 @@ public:
virtual void PragmaWarningPop(SourceLocation Loc) {
}
+ /// \brief Callback invoked when a \#pragma clang assume_nonnull begin directive
+ /// is read.
+ virtual void PragmaAssumeNonNullBegin(SourceLocation Loc) {}
+
+ /// \brief Callback invoked when a \#pragma clang assume_nonnull end directive
+ /// is read.
+ virtual void PragmaAssumeNonNullEnd(SourceLocation Loc) {}
+
/// \brief Called by Preprocessor::HandleMacroExpandedIdentifier when a
/// macro invocation is found.
virtual void MacroExpands(const Token &MacroNameTok,
@@ -266,7 +274,10 @@ public:
/// \brief Hook called when a source range is skipped.
/// \param Range The SourceRange that was skipped. The range begins at the
/// \#if/\#else directive and ends after the \#endif/\#else directive.
- virtual void SourceRangeSkipped(SourceRange Range) {
+ /// \param EndifLoc The end location of the 'endif' token, which may precede
+ /// the range skipped by the directive (e.g excluding comments after an
+ /// 'endif').
+ virtual void SourceRangeSkipped(SourceRange Range, SourceLocation EndifLoc) {
}
enum ConditionValueKind {
@@ -381,6 +392,12 @@ public:
Second->Ident(Loc, str);
}
+ void PragmaDirective(SourceLocation Loc,
+ PragmaIntroducerKind Introducer) override {
+ First->PragmaDirective(Loc, Introducer);
+ Second->PragmaDirective(Loc, Introducer);
+ }
+
void PragmaComment(SourceLocation Loc, const IdentifierInfo *Kind,
StringRef Str) override {
First->PragmaComment(Loc, Kind, Str);
@@ -393,6 +410,11 @@ public:
Second->PragmaDetectMismatch(Loc, Name, Value);
}
+ void PragmaDebug(SourceLocation Loc, StringRef DebugType) override {
+ First->PragmaDebug(Loc, DebugType);
+ Second->PragmaDebug(Loc, DebugType);
+ }
+
void PragmaMessage(SourceLocation Loc, StringRef Namespace,
PragmaMessageKind Kind, StringRef Str) override {
First->PragmaMessage(Loc, Namespace, Kind, Str);
@@ -437,6 +459,16 @@ public:
Second->PragmaWarningPop(Loc);
}
+ void PragmaAssumeNonNullBegin(SourceLocation Loc) override {
+ First->PragmaAssumeNonNullBegin(Loc);
+ Second->PragmaAssumeNonNullBegin(Loc);
+ }
+
+ void PragmaAssumeNonNullEnd(SourceLocation Loc) override {
+ First->PragmaAssumeNonNullEnd(Loc);
+ Second->PragmaAssumeNonNullEnd(Loc);
+ }
+
void MacroExpands(const Token &MacroNameTok, const MacroDefinition &MD,
SourceRange Range, const MacroArgs *Args) override {
First->MacroExpands(MacroNameTok, MD, Range, Args);
@@ -462,9 +494,9 @@ public:
Second->Defined(MacroNameTok, MD, Range);
}
- void SourceRangeSkipped(SourceRange Range) override {
- First->SourceRangeSkipped(Range);
- Second->SourceRangeSkipped(Range);
+ void SourceRangeSkipped(SourceRange Range, SourceLocation EndifLoc) override {
+ First->SourceRangeSkipped(Range, EndifLoc);
+ Second->SourceRangeSkipped(Range, EndifLoc);
}
/// \brief Hook called whenever an \#if is seen.
diff --git a/include/clang/Lex/PTHLexer.h b/include/clang/Lex/PTHLexer.h
index f96af665b157..f122a008e4aa 100644
--- a/include/clang/Lex/PTHLexer.h
+++ b/include/clang/Lex/PTHLexer.h
@@ -1,4 +1,4 @@
-//===--- PTHLexer.h - Lexer based on Pre-tokenized input --------*- C++ -*-===//
+//===- PTHLexer.h - Lexer based on Pre-tokenized input ----------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -14,12 +14,15 @@
#ifndef LLVM_CLANG_LEX_PTHLEXER_H
#define LLVM_CLANG_LEX_PTHLEXER_H
+#include "clang/Basic/SourceLocation.h"
+#include "clang/Basic/TokenKinds.h"
#include "clang/Lex/PreprocessorLexer.h"
+#include "clang/Lex/Token.h"
namespace clang {
+class Preprocessor;
class PTHManager;
-class PTHSpellingSearch;
class PTHLexer : public PreprocessorLexer {
SourceLocation FileStartLoc;
@@ -33,7 +36,7 @@ class PTHLexer : public PreprocessorLexer {
/// LastHashTokPtr - Pointer into TokBuf of the last processed '#'
/// token that appears at the start of a line.
- const unsigned char* LastHashTokPtr;
+ const unsigned char* LastHashTokPtr = nullptr;
/// PPCond - Pointer to a side table in the PTH file that provides a
/// a concise summary of the preprocessor conditional block structure.
@@ -44,11 +47,8 @@ class PTHLexer : public PreprocessorLexer {
/// to process when doing quick skipping of preprocessor blocks.
const unsigned char* CurPPCondPtr;
- PTHLexer(const PTHLexer &) = delete;
- void operator=(const PTHLexer &) = delete;
-
/// ReadToken - Used by PTHLexer to read tokens TokBuf.
- void ReadToken(Token& T);
+ void ReadToken(Token &T);
bool LexEndOfFile(Token &Result);
@@ -61,10 +61,13 @@ protected:
friend class PTHManager;
/// Create a PTHLexer for the specified token stream.
- PTHLexer(Preprocessor& pp, FileID FID, const unsigned char *D,
+ PTHLexer(Preprocessor &pp, FileID FID, const unsigned char *D,
const unsigned char* ppcond, PTHManager &PM);
+
public:
- ~PTHLexer() override {}
+ PTHLexer(const PTHLexer &) = delete;
+ PTHLexer &operator=(const PTHLexer &) = delete;
+ ~PTHLexer() override = default;
/// Lex - Return the next token.
bool Lex(Token &Tok);
@@ -99,6 +102,6 @@ public:
bool SkipBlock();
};
-} // end namespace clang
+} // namespace clang
-#endif
+#endif // LLVM_CLANG_LEX_PTHLEXER_H
diff --git a/include/clang/Lex/PTHManager.h b/include/clang/Lex/PTHManager.h
index f4e4774429f9..483b69f23a9c 100644
--- a/include/clang/Lex/PTHManager.h
+++ b/include/clang/Lex/PTHManager.h
@@ -1,4 +1,4 @@
-//===--- PTHManager.h - Manager object for PTH processing -------*- C++ -*-===//
+//===- PTHManager.h - Manager object for PTH processing ---------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -17,30 +17,33 @@
#include "clang/Basic/IdentifierTable.h"
#include "clang/Basic/SourceLocation.h"
#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Allocator.h"
#include "llvm/Support/OnDiskHashTable.h"
+#include <memory>
namespace llvm {
- class MemoryBuffer;
-}
+
+class MemoryBuffer;
+
+} // namespace llvm
namespace clang {
-class FileEntry;
-class Preprocessor;
-class PTHLexer;
class DiagnosticsEngine;
class FileSystemStatCache;
+class Preprocessor;
+class PTHLexer;
class PTHManager : public IdentifierInfoLookup {
friend class PTHLexer;
-
friend class PTHStatCache;
- class PTHStringLookupTrait;
class PTHFileLookupTrait;
- typedef llvm::OnDiskChainedHashTable<PTHStringLookupTrait> PTHStringIdLookup;
- typedef llvm::OnDiskChainedHashTable<PTHFileLookupTrait> PTHFileLookup;
+ class PTHStringLookupTrait;
+
+ using PTHStringIdLookup = llvm::OnDiskChainedHashTable<PTHStringLookupTrait>;
+ using PTHFileLookup = llvm::OnDiskChainedHashTable<PTHFileLookupTrait>;
/// The memory mapped PTH file.
std::unique_ptr<const llvm::MemoryBuffer> Buf;
@@ -70,7 +73,7 @@ class PTHManager : public IdentifierInfoLookup {
/// PP - The Preprocessor object that will use this PTHManager to create
/// PTHLexer objects.
- Preprocessor* PP;
+ Preprocessor* PP = nullptr;
/// SpellingBase - The base offset within the PTH memory buffer that
/// contains the cached spellings for literals.
@@ -89,16 +92,13 @@ class PTHManager : public IdentifierInfoLookup {
std::unique_ptr<PTHStringIdLookup> stringIdLookup, unsigned numIds,
const unsigned char *spellingBase, const char *originalSourceFile);
- PTHManager(const PTHManager &) = delete;
- void operator=(const PTHManager &) = delete;
-
/// getSpellingAtPTHOffset - Used by PTHLexer classes to get the cached
/// spelling for a token.
unsigned getSpellingAtPTHOffset(unsigned PTHOffset, const char*& Buffer);
/// GetIdentifierInfo - Used to reconstruct IdentifierInfo objects from the
/// PTH file.
- inline IdentifierInfo* GetIdentifierInfo(unsigned PersistentID) {
+ IdentifierInfo *GetIdentifierInfo(unsigned PersistentID) {
// Check if the IdentifierInfo has already been resolved.
if (IdentifierInfo* II = PerIDCache[PersistentID])
return II;
@@ -110,6 +110,8 @@ public:
// The current PTH version.
enum { Version = 10 };
+ PTHManager(const PTHManager &) = delete;
+ PTHManager &operator=(const PTHManager &) = delete;
~PTHManager() override;
/// getOriginalSourceFile - Return the full path to the original header
@@ -120,18 +122,18 @@ public:
/// get - Return the identifier token info for the specified named identifier.
/// Unlike the version in IdentifierTable, this returns a pointer instead
- /// of a reference. If the pointer is NULL then the IdentifierInfo cannot
+ /// of a reference. If the pointer is nullptr then the IdentifierInfo cannot
/// be found.
IdentifierInfo *get(StringRef Name) override;
/// Create - This method creates PTHManager objects. The 'file' argument
- /// is the name of the PTH file. This method returns NULL upon failure.
+ /// is the name of the PTH file. This method returns nullptr upon failure.
static PTHManager *Create(StringRef file, DiagnosticsEngine &Diags);
void setPreprocessor(Preprocessor *pp) { PP = pp; }
/// CreateLexer - Return a PTHLexer that "lexes" the cached tokens for the
- /// specified file. This method returns NULL if no cached tokens exist.
+ /// specified file. This method returns nullptr if no cached tokens exist.
/// It is the responsibility of the caller to 'delete' the returned object.
PTHLexer *CreateLexer(FileID FID);
@@ -142,6 +144,6 @@ public:
std::unique_ptr<FileSystemStatCache> createStatCache();
};
-} // end namespace clang
+} // namespace clang
-#endif
+#endif // LLVM_CLANG_LEX_PTHMANAGER_H
diff --git a/include/clang/Lex/Pragma.h b/include/clang/Lex/Pragma.h
index 274f0dad3dd0..090ae2a98236 100644
--- a/include/clang/Lex/Pragma.h
+++ b/include/clang/Lex/Pragma.h
@@ -1,4 +1,4 @@
-//===--- Pragma.h - Pragma registration and handling ------------*- C++ -*-===//
+//===- Pragma.h - Pragma registration and handling --------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -17,13 +17,13 @@
#include "clang/Basic/LLVM.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringRef.h"
-#include <cassert>
+#include <string>
namespace clang {
- class Preprocessor;
- class Token;
- class IdentifierInfo;
- class PragmaNamespace;
+
+class PragmaNamespace;
+class Preprocessor;
+class Token;
/**
* \brief Describes how the pragma was introduced, e.g., with \#pragma,
@@ -58,9 +58,10 @@ namespace clang {
/// pragmas.
class PragmaHandler {
std::string Name;
+
public:
+ PragmaHandler() = default;
explicit PragmaHandler(StringRef name) : Name(name) {}
- PragmaHandler() {}
virtual ~PragmaHandler();
StringRef getName() const { return Name; }
@@ -89,8 +90,8 @@ public:
class PragmaNamespace : public PragmaHandler {
/// Handlers - This is a map of the handlers in this namespace with their name
/// as key.
- ///
- llvm::StringMap<PragmaHandler*> Handlers;
+ llvm::StringMap<PragmaHandler *> Handlers;
+
public:
explicit PragmaNamespace(StringRef Name) : PragmaHandler(Name) {}
~PragmaNamespace() override;
@@ -103,16 +104,13 @@ public:
bool IgnoreNull = true) const;
/// AddPragma - Add a pragma to this namespace.
- ///
void AddPragma(PragmaHandler *Handler);
/// RemovePragmaHandler - Remove the given handler from the
/// namespace.
void RemovePragmaHandler(PragmaHandler *Handler);
- bool IsEmpty() {
- return Handlers.empty();
- }
+ bool IsEmpty() const { return Handlers.empty(); }
void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
Token &FirstToken) override;
@@ -120,7 +118,6 @@ public:
PragmaNamespace *getIfNamespace() override { return this; }
};
+} // namespace clang
-} // end namespace clang
-
-#endif
+#endif // LLVM_CLANG_LEX_PRAGMA_H
diff --git a/include/clang/Lex/PreprocessingRecord.h b/include/clang/Lex/PreprocessingRecord.h
index fc2c50700400..5f7a6efcef10 100644
--- a/include/clang/Lex/PreprocessingRecord.h
+++ b/include/clang/Lex/PreprocessingRecord.h
@@ -1,4 +1,4 @@
-//===--- PreprocessingRecord.h - Record of Preprocessing --------*- C++ -*-===//
+//===- PreprocessingRecord.h - Record of Preprocessing ----------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -11,24 +11,33 @@
// of what occurred during preprocessing.
//
//===----------------------------------------------------------------------===//
+
#ifndef LLVM_CLANG_LEX_PREPROCESSINGRECORD_H
#define LLVM_CLANG_LEX_PREPROCESSINGRECORD_H
-#include "clang/Basic/IdentifierTable.h"
+#include "clang/Basic/LLVM.h"
#include "clang/Basic/SourceLocation.h"
#include "clang/Lex/PPCallbacks.h"
#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/None.h"
#include "llvm/ADT/Optional.h"
+#include "llvm/ADT/PointerUnion.h"
+#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/iterator.h"
+#include "llvm/ADT/iterator_range.h"
#include "llvm/Support/Allocator.h"
#include "llvm/Support/Compiler.h"
+#include <cassert>
+#include <cstddef>
+#include <iterator>
+#include <utility>
#include <vector>
namespace clang {
- class IdentifierInfo;
- class MacroInfo;
- class PreprocessingRecord;
-}
+
+class PreprocessingRecord;
+
+} // namespace clang
/// \brief Allocates memory within a Clang preprocessing record.
void *operator new(size_t bytes, clang::PreprocessingRecord &PR,
@@ -39,8 +48,12 @@ void operator delete(void *ptr, clang::PreprocessingRecord &PR,
unsigned) noexcept;
namespace clang {
- class MacroDefinitionRecord;
- class FileEntry;
+
+class FileEntry;
+class IdentifierInfo;
+class MacroInfo;
+class SourceManager;
+class Token;
/// \brief Base class that describes a preprocessed entity, which may be a
/// preprocessor directive or macro expansion.
@@ -78,11 +91,11 @@ namespace clang {
SourceRange Range;
protected:
- PreprocessedEntity(EntityKind Kind, SourceRange Range)
- : Kind(Kind), Range(Range) { }
-
friend class PreprocessingRecord;
+ PreprocessedEntity(EntityKind Kind, SourceRange Range)
+ : Kind(Kind), Range(Range) {}
+
public:
/// \brief Retrieve the kind of preprocessed entity stored in this object.
EntityKind getKind() const { return Kind; }
@@ -122,7 +135,7 @@ namespace clang {
class PreprocessingDirective : public PreprocessedEntity {
public:
PreprocessingDirective(EntityKind Kind, SourceRange Range)
- : PreprocessedEntity(Kind, Range) { }
+ : PreprocessedEntity(Kind, Range) {}
// Implement isa/cast/dyncast/etc.
static bool classof(const PreprocessedEntity *PD) {
@@ -199,10 +212,13 @@ namespace clang {
enum InclusionKind {
/// \brief An \c \#include directive.
Include,
+
/// \brief An Objective-C \c \#import directive.
Import,
+
/// \brief A GNU \c \#include_next directive.
IncludeNext,
+
/// \brief A Clang \c \#__include_macros directive.
IncludeMacros
};
@@ -316,11 +332,14 @@ namespace clang {
/// value 1 corresponds to element 0 in the local entities vector,
/// value 2 corresponds to element 1 in the local entities vector, etc.
class PPEntityID {
- int ID;
- explicit PPEntityID(int ID) : ID(ID) {}
friend class PreprocessingRecord;
+
+ int ID = 0;
+
+ explicit PPEntityID(int ID) : ID(ID) {}
+
public:
- PPEntityID() : ID(0) {}
+ PPEntityID() = default;
};
static PPEntityID getPPEntityID(unsigned Index, bool isLoaded) {
@@ -331,7 +350,7 @@ namespace clang {
llvm::DenseMap<const MacroInfo *, MacroDefinitionRecord *> MacroDefinitions;
/// \brief External source of preprocessed entities.
- ExternalPreprocessingRecordSource *ExternalSource;
+ ExternalPreprocessingRecordSource *ExternalSource = nullptr;
/// \brief Retrieve the preprocessed entity at the given ID.
PreprocessedEntity *getPreprocessedEntity(PPEntityID PPID);
@@ -371,7 +390,7 @@ namespace clang {
}
/// \brief Deallocate memory in the preprocessing record.
- void Deallocate(void *Ptr) { }
+ void Deallocate(void *Ptr) {}
size_t getTotalMemory() const;
@@ -397,11 +416,12 @@ namespace clang {
iterator, int, std::random_access_iterator_tag,
PreprocessedEntity *, int, PreprocessedEntity *,
PreprocessedEntity *> {
+ friend class PreprocessingRecord;
+
PreprocessingRecord *Self;
iterator(PreprocessingRecord *Self, int Position)
: iterator::iterator_adaptor_base(Position), Self(Self) {}
- friend class PreprocessingRecord;
public:
iterator() : iterator(nullptr, 0) {}
@@ -451,7 +471,6 @@ namespace clang {
/// encompasses.
///
/// \param R the range to look for preprocessed entities.
- ///
llvm::iterator_range<iterator>
getPreprocessedEntitiesInRange(SourceRange R);
@@ -485,6 +504,9 @@ namespace clang {
}
private:
+ friend class ASTReader;
+ friend class ASTWriter;
+
void MacroExpands(const Token &Id, const MacroDefinition &MD,
SourceRange Range, const MacroArgs *Args) override;
void MacroDefined(const Token &Id, const MacroDirective *MD) override;
@@ -500,11 +522,13 @@ namespace clang {
const MacroDefinition &MD) override;
void Ifndef(SourceLocation Loc, const Token &MacroNameTok,
const MacroDefinition &MD) override;
+
/// \brief Hook called whenever the 'defined' operator is seen.
void Defined(const Token &MacroNameTok, const MacroDefinition &MD,
SourceRange Range) override;
- void SourceRangeSkipped(SourceRange Range) override;
+ void SourceRangeSkipped(SourceRange Range,
+ SourceLocation EndifLoc) override;
void addMacroExpansion(const Token &Id, const MacroInfo *MI,
SourceRange Range);
@@ -517,11 +541,9 @@ namespace clang {
} CachedRangeQuery;
std::pair<int, int> getPreprocessedEntitiesInRangeSlow(SourceRange R);
-
- friend class ASTReader;
- friend class ASTWriter;
};
-} // end namespace clang
+
+} // namespace clang
inline void *operator new(size_t bytes, clang::PreprocessingRecord &PR,
unsigned alignment) noexcept {
diff --git a/include/clang/Lex/Preprocessor.h b/include/clang/Lex/Preprocessor.h
index dba4b80f6071..485600f12232 100644
--- a/include/clang/Lex/Preprocessor.h
+++ b/include/clang/Lex/Preprocessor.h
@@ -1,4 +1,4 @@
-//===--- Preprocessor.h - C Language Family Preprocessor --------*- C++ -*-===//
+//===- Preprocessor.h - C Language Family Preprocessor ----------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -6,10 +6,10 @@
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
-///
+//
/// \file
/// \brief Defines the clang::Preprocessor interface.
-///
+//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_LEX_PREPROCESSOR_H
@@ -18,48 +18,70 @@
#include "clang/Basic/Builtins.h"
#include "clang/Basic/Diagnostic.h"
#include "clang/Basic/IdentifierTable.h"
+#include "clang/Basic/LLVM.h"
+#include "clang/Basic/LangOptions.h"
+#include "clang/Basic/Module.h"
#include "clang/Basic/SourceLocation.h"
+#include "clang/Basic/SourceManager.h"
+#include "clang/Basic/TokenKinds.h"
#include "clang/Lex/Lexer.h"
#include "clang/Lex/MacroInfo.h"
+#include "clang/Lex/ModuleLoader.h"
#include "clang/Lex/ModuleMap.h"
#include "clang/Lex/PPCallbacks.h"
#include "clang/Lex/PTHLexer.h"
+#include "clang/Lex/Token.h"
#include "clang/Lex/TokenLexer.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/IntrusiveRefCntPtr.h"
+#include "llvm/ADT/FoldingSet.h"
+#include "llvm/ADT/None.h"
+#include "llvm/ADT/Optional.h"
+#include "llvm/ADT/PointerUnion.h"
+#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/TinyPtrVector.h"
+#include "llvm/ADT/iterator_range.h"
#include "llvm/Support/Allocator.h"
+#include "llvm/Support/Casting.h"
#include "llvm/Support/Registry.h"
+#include <cassert>
+#include <cstddef>
+#include <cstdint>
#include <memory>
+#include <map>
+#include <string>
+#include <utility>
#include <vector>
namespace llvm {
- template<unsigned InternalLen> class SmallString;
-}
+
+template<unsigned InternalLen> class SmallString;
+
+} // namespace llvm
namespace clang {
-class SourceManager;
+class CodeCompletionHandler;
+class CommentHandler;
+class DirectoryEntry;
+class DirectoryLookup;
class ExternalPreprocessorSource;
-class FileManager;
class FileEntry;
+class FileManager;
class HeaderSearch;
+class MacroArgs;
class MemoryBufferCache;
-class PragmaNamespace;
class PragmaHandler;
-class CommentHandler;
-class ScratchBuffer;
-class TargetInfo;
-class PPCallbacks;
-class CodeCompletionHandler;
-class DirectoryLookup;
+class PragmaNamespace;
class PreprocessingRecord;
-class ModuleLoader;
-class PTHManager;
+class PreprocessorLexer;
class PreprocessorOptions;
+class PTHManager;
+class ScratchBuffer;
+class TargetInfo;
/// \brief Stores token information for comparing actual tokens with
/// predefined values. Only handles simple tokens and identifiers.
@@ -75,7 +97,9 @@ public:
assert(!tok::isLiteral(Kind) && "Literals are not supported.");
assert(!tok::isAnnotation(Kind) && "Annotations are not supported.");
}
+
TokenValue(IdentifierInfo *II) : Kind(tok::identifier), II(II) {}
+
bool operator==(const Token &Tok) const {
return Tok.getKind() == Kind &&
(!II || II == Tok.getIdentifierInfo());
@@ -84,9 +108,14 @@ public:
/// \brief Context in which macro name is used.
enum MacroUse {
- MU_Other = 0, // other than #define or #undef
- MU_Define = 1, // macro name specified in #define
- MU_Undef = 2 // macro name specified in #undef
+ // other than #define or #undef
+ MU_Other = 0,
+
+ // macro name specified in #define
+ MU_Define = 1,
+
+ // macro name specified in #undef
+ MU_Undef = 2
};
/// \brief Engages in a tight little dance with the lexer to efficiently
@@ -96,11 +125,14 @@ enum MacroUse {
/// know anything about preprocessor-level issues like the \#include stack,
/// token expansion, etc.
class Preprocessor {
+ friend class VAOptDefinitionContext;
+ friend class VariadicMacroScopeGuard;
+
std::shared_ptr<PreprocessorOptions> PPOpts;
DiagnosticsEngine *Diags;
LangOptions &LangOpts;
- const TargetInfo *Target;
- const TargetInfo *AuxTarget;
+ const TargetInfo *Target = nullptr;
+ const TargetInfo *AuxTarget = nullptr;
FileManager &FileMgr;
SourceManager &SourceMgr;
MemoryBufferCache &PCMCache;
@@ -111,7 +143,6 @@ class Preprocessor {
/// \brief External source of macros.
ExternalPreprocessorSource *ExternalSource;
-
/// An optional PTHManager object used for getting tokens from
/// a token cache rather than lexing the original source file.
std::unique_ptr<PTHManager> PTH;
@@ -130,6 +161,7 @@ class Preprocessor {
IdentifierInfo *Ident_Pragma, *Ident__pragma; // _Pragma, __pragma
IdentifierInfo *Ident__identifier; // __identifier
IdentifierInfo *Ident__VA_ARGS__; // __VA_ARGS__
+ IdentifierInfo *Ident__VA_OPT__; // __VA_OPT__
IdentifierInfo *Ident__has_feature; // __has_feature
IdentifierInfo *Ident__has_extension; // __has_extension
IdentifierInfo *Ident__has_builtin; // __has_builtin
@@ -141,10 +173,17 @@ class Preprocessor {
IdentifierInfo *Ident__building_module; // __building_module
IdentifierInfo *Ident__MODULE__; // __MODULE__
IdentifierInfo *Ident__has_cpp_attribute; // __has_cpp_attribute
+ IdentifierInfo *Ident__has_c_attribute; // __has_c_attribute
IdentifierInfo *Ident__has_declspec; // __has_declspec_attribute
+ IdentifierInfo *Ident__is_target_arch; // __is_target_arch
+ IdentifierInfo *Ident__is_target_vendor; // __is_target_vendor
+ IdentifierInfo *Ident__is_target_os; // __is_target_os
+ IdentifierInfo *Ident__is_target_environment; // __is_target_environment
SourceLocation DATELoc, TIMELoc;
- unsigned CounterValue; // Next __COUNTER__ value.
+
+ // Next __COUNTER__ value, starts at 0.
+ unsigned CounterValue = 0;
enum {
/// \brief Maximum depth of \#includes.
@@ -218,19 +257,19 @@ class Preprocessor {
/// \brief True if we want to ignore EOF token and continue later on (thus
/// avoid tearing the Lexer and etc. down).
- bool IncrementalProcessing;
+ bool IncrementalProcessing = false;
/// The kind of translation unit we are processing.
TranslationUnitKind TUKind;
/// \brief The code-completion handler.
- CodeCompletionHandler *CodeComplete;
+ CodeCompletionHandler *CodeComplete = nullptr;
/// \brief The file that we're performing code-completion for, if any.
- const FileEntry *CodeCompletionFile;
+ const FileEntry *CodeCompletionFile = nullptr;
/// \brief The offset in file for the code-completion point.
- unsigned CodeCompletionOffset;
+ unsigned CodeCompletionOffset = 0;
/// \brief The location for the code-completion point. This gets instantiated
/// when the CodeCompletionFile gets \#include'ed for preprocessing.
@@ -250,11 +289,11 @@ class Preprocessor {
SmallVector<std::pair<IdentifierInfo *, SourceLocation>, 2> ModuleImportPath;
/// \brief Whether the last token we lexed was an '@'.
- bool LastTokenWasAt;
+ bool LastTokenWasAt = false;
/// \brief Whether the module import expects an identifier next. Otherwise,
/// it expects a '.' or ';'.
- bool ModuleImportExpectsIdentifier;
+ bool ModuleImportExpectsIdentifier = false;
/// \brief The source location of the currently-active
/// \#pragma clang arc_cf_code_audited begin.
@@ -265,16 +304,16 @@ class Preprocessor {
SourceLocation PragmaAssumeNonNullLoc;
/// \brief True if we hit the code-completion point.
- bool CodeCompletionReached;
+ bool CodeCompletionReached = false;
/// \brief The code completion token containing the information
/// on the stem that is to be code completed.
- IdentifierInfo *CodeCompletionII;
+ IdentifierInfo *CodeCompletionII = nullptr;
/// \brief The directory that the main file should be considered to occupy,
/// if it does not correspond to a real file (as happens when building a
/// module).
- const DirectoryEntry *MainFileDir;
+ const DirectoryEntry *MainFileDir = nullptr;
/// \brief The number of bytes that we will initially skip when entering the
/// main file, along with a flag that indicates whether skipping this number
@@ -283,6 +322,26 @@ class Preprocessor {
/// This is used when loading a precompiled preamble.
std::pair<int, bool> SkipMainFilePreamble;
+public:
+ struct PreambleSkipInfo {
+ SourceLocation HashTokenLoc;
+ SourceLocation IfTokenLoc;
+ bool FoundNonSkipPortion;
+ bool FoundElse;
+ SourceLocation ElseLoc;
+
+ PreambleSkipInfo(SourceLocation HashTokenLoc, SourceLocation IfTokenLoc,
+ bool FoundNonSkipPortion, bool FoundElse,
+ SourceLocation ElseLoc)
+ : HashTokenLoc(HashTokenLoc), IfTokenLoc(IfTokenLoc),
+ FoundNonSkipPortion(FoundNonSkipPortion), FoundElse(FoundElse),
+ ElseLoc(ElseLoc) {}
+ };
+
+private:
+ friend class ASTReader;
+ friend class MacroArgs;
+
class PreambleConditionalStackStore {
enum State {
Off = 0,
@@ -291,7 +350,7 @@ class Preprocessor {
};
public:
- PreambleConditionalStackStore() : ConditionalStackState(Off) {}
+ PreambleConditionalStackStore() = default;
void startRecording() { ConditionalStackState = Recording; }
void startReplaying() { ConditionalStackState = Replaying; }
@@ -316,9 +375,15 @@ class Preprocessor {
bool hasRecordedPreamble() const { return !ConditionalStack.empty(); }
+ bool reachedEOFWhileSkipping() const { return SkipInfo.hasValue(); }
+
+ void clearSkipInfo() { SkipInfo.reset(); }
+
+ llvm::Optional<PreambleSkipInfo> SkipInfo;
+
private:
SmallVector<PPConditionalInfo, 4> ConditionalStack;
- State ConditionalStackState;
+ State ConditionalStackState = Off;
} PreambleConditionalStack;
/// \brief The current top of the stack that we're lexing from if
@@ -337,14 +402,14 @@ class Preprocessor {
/// if not expanding a macro.
///
/// This is an alias for either CurLexer or CurPTHLexer.
- PreprocessorLexer *CurPPLexer;
+ PreprocessorLexer *CurPPLexer = nullptr;
/// \brief Used to find the current FileEntry, if CurLexer is non-null
/// and if applicable.
///
/// This allows us to implement \#include_next and find directory-specific
/// properties.
- const DirectoryLookup *CurDirLookup;
+ const DirectoryLookup *CurDirLookup = nullptr;
/// \brief The current macro we are expanding, if we are expanding a macro.
///
@@ -358,11 +423,11 @@ class Preprocessor {
CLK_TokenLexer,
CLK_CachingLexer,
CLK_LexAfterModuleImport
- } CurLexerKind;
+ } CurLexerKind = CLK_Lexer;
/// \brief If the current lexer is for a submodule that is being built, this
/// is that submodule.
- Module *CurLexerSubmodule;
+ Module *CurLexerSubmodule = nullptr;
/// \brief Keeps track of the stack of files currently
/// \#included, and macros currently being expanded from, not counting
@@ -401,27 +466,31 @@ class Preprocessor {
Token Tok;
MacroDefinition MD;
SourceRange Range;
+
MacroExpandsInfo(Token Tok, MacroDefinition MD, SourceRange Range)
- : Tok(Tok), MD(MD), Range(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;
+ llvm::TinyPtrVector<ModuleMacro *> ActiveModuleMacros;
+
/// The generation number at which we last updated ActiveModuleMacros.
/// \see Preprocessor::VisibleModules.
- unsigned ActiveModuleMacrosGeneration;
+ unsigned ActiveModuleMacrosGeneration = 0;
+
/// Whether this macro name is ambiguous.
- bool IsAmbiguous;
+ bool IsAmbiguous = false;
+
/// The module macros that are overridden by this macro.
- llvm::TinyPtrVector<ModuleMacro*> OverriddenMacros;
+ llvm::TinyPtrVector<ModuleMacro *> OverriddenMacros;
+
+ ModuleMacroInfo(MacroDirective *MD) : MD(MD) {}
};
/// The state of a macro for an identifier.
@@ -456,15 +525,18 @@ class Preprocessor {
public:
MacroState() : MacroState(nullptr) {}
MacroState(MacroDirective *MD) : State(MD) {}
+
MacroState(MacroState &&O) noexcept : State(O.State) {
O.State = (MacroDirective *)nullptr;
}
+
MacroState &operator=(MacroState &&O) noexcept {
auto S = O.State;
O.State = (MacroDirective *)nullptr;
State = S;
return *this;
}
+
~MacroState() {
if (auto *Info = State.dyn_cast<ModuleMacroInfo*>())
Info->~ModuleMacroInfo();
@@ -475,6 +547,7 @@ class Preprocessor {
return Info->MD;
return State.get<MacroDirective*>();
}
+
void setLatest(MacroDirective *MD) {
if (auto *Info = State.dyn_cast<ModuleMacroInfo*>())
Info->MD = MD;
@@ -486,6 +559,7 @@ class Preprocessor {
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))
@@ -498,7 +572,7 @@ class Preprocessor {
// FIXME: Incorporate module macros into the result of this.
if (auto *Latest = getLatest())
return Latest->findDirectiveAtLoc(Loc, SourceMgr);
- return MacroDirective::DefInfo();
+ return {};
}
void overrideActiveModuleMacros(Preprocessor &PP, IdentifierInfo *II) {
@@ -510,11 +584,13 @@ class Preprocessor {
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*>();
@@ -537,31 +613,33 @@ class Preprocessor {
/// the reverse order (the latest one is in the head of the list).
///
/// This mapping lives within the \p CurSubmoduleState.
- typedef llvm::DenseMap<const IdentifierInfo *, MacroState> MacroMap;
-
- friend class ASTReader;
+ using MacroMap = llvm::DenseMap<const IdentifierInfo *, MacroState>;
struct SubmoduleState;
/// \brief Information about a submodule that we're currently building.
struct BuildingSubmoduleInfo {
- BuildingSubmoduleInfo(Module *M, SourceLocation ImportLoc, bool IsPragma,
- SubmoduleState *OuterSubmoduleState,
- unsigned OuterPendingModuleMacroNames)
- : M(M), ImportLoc(ImportLoc), IsPragma(IsPragma),
- OuterSubmoduleState(OuterSubmoduleState),
- OuterPendingModuleMacroNames(OuterPendingModuleMacroNames) {}
-
/// The module that we are building.
Module *M;
+
/// The location at which the module was included.
SourceLocation ImportLoc;
+
/// Whether we entered this submodule via a pragma.
bool IsPragma;
+
/// The previous SubmoduleState.
SubmoduleState *OuterSubmoduleState;
+
/// The number of pending module macro names when we started building this.
unsigned OuterPendingModuleMacroNames;
+
+ BuildingSubmoduleInfo(Module *M, SourceLocation ImportLoc, bool IsPragma,
+ SubmoduleState *OuterSubmoduleState,
+ unsigned OuterPendingModuleMacroNames)
+ : M(M), ImportLoc(ImportLoc), IsPragma(IsPragma),
+ OuterSubmoduleState(OuterSubmoduleState),
+ OuterPendingModuleMacroNames(OuterPendingModuleMacroNames) {}
};
SmallVector<BuildingSubmoduleInfo, 8> BuildingSubmoduleStack;
@@ -569,12 +647,14 @@ class Preprocessor {
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;
+ std::map<Module *, SubmoduleState> Submodules;
/// The preprocessor state for preprocessing outside of any submodule.
SubmoduleState NullSubmoduleState;
@@ -587,11 +667,11 @@ class Preprocessor {
llvm::FoldingSet<ModuleMacro> ModuleMacros;
/// The names of potential module macros that we've not yet processed.
- llvm::SmallVector<const IdentifierInfo*, 32> PendingModuleMacroNames;
+ llvm::SmallVector<const IdentifierInfo *, 32> PendingModuleMacroNames;
/// The list of module macros, for each identifier, that are not overridden by
/// any other module macro.
- llvm::DenseMap<const IdentifierInfo *, llvm::TinyPtrVector<ModuleMacro*>>
+ llvm::DenseMap<const IdentifierInfo *, llvm::TinyPtrVector<ModuleMacro *>>
LeafModuleMacros;
/// \brief Macros that we want to warn because they are not used at the end
@@ -603,25 +683,35 @@ class Preprocessor {
/// just so that we can report that they are unused, we just warn using
/// the SourceLocations of this set (that will be filled by the ASTReader).
/// We are using SmallPtrSet instead of a vector for faster removal.
- typedef llvm::SmallPtrSet<SourceLocation, 32> WarnUnusedMacroLocsTy;
+ using WarnUnusedMacroLocsTy = llvm::SmallPtrSet<SourceLocation, 32>;
WarnUnusedMacroLocsTy WarnUnusedMacroLocs;
/// \brief A "freelist" of MacroArg objects that can be
/// reused for quick allocation.
- MacroArgs *MacroArgCache;
- friend class MacroArgs;
+ MacroArgs *MacroArgCache = nullptr;
/// For each IdentifierInfo used in a \#pragma push_macro directive,
/// we keep a MacroInfo stack used to restore the previous macro value.
- llvm::DenseMap<IdentifierInfo*, std::vector<MacroInfo*> > PragmaPushMacroInfo;
+ llvm::DenseMap<IdentifierInfo *, std::vector<MacroInfo *>>
+ PragmaPushMacroInfo;
// Various statistics we track for performance analysis.
- unsigned NumDirectives, NumDefined, NumUndefined, NumPragma;
- unsigned NumIf, NumElse, NumEndif;
- unsigned NumEnteredSourceFiles, MaxIncludeStackDepth;
- unsigned NumMacroExpanded, NumFnMacroExpanded, NumBuiltinMacroExpanded;
- unsigned NumFastMacroExpanded, NumTokenPaste, NumFastTokenPaste;
- unsigned NumSkipped;
+ unsigned NumDirectives = 0;
+ unsigned NumDefined = 0;
+ unsigned NumUndefined = 0;
+ unsigned NumPragma = 0;
+ unsigned NumIf = 0;
+ unsigned NumElse = 0;
+ unsigned NumEndif = 0;
+ unsigned NumEnteredSourceFiles = 0;
+ unsigned MaxIncludeStackDepth = 0;
+ unsigned NumMacroExpanded = 0;
+ unsigned NumFnMacroExpanded = 0;
+ unsigned NumBuiltinMacroExpanded = 0;
+ unsigned NumFastMacroExpanded = 0;
+ unsigned NumTokenPaste = 0;
+ unsigned NumFastTokenPaste = 0;
+ unsigned NumSkipped = 0;
/// \brief The predefined macros that preprocessor should use from the
/// command line etc.
@@ -643,17 +733,17 @@ class Preprocessor {
/// going to lex in the cache and when it finishes the tokens are removed
/// from the end of the cache.
SmallVector<Token, 16> MacroExpandedTokens;
- std::vector<std::pair<TokenLexer *, size_t> > MacroExpandingLexersStack;
+ std::vector<std::pair<TokenLexer *, size_t>> MacroExpandingLexersStack;
/// \brief A record of the macro definitions and expansions that
/// occurred during preprocessing.
///
/// This is an optional side structure that can be enabled with
/// \c createPreprocessingRecord() prior to preprocessing.
- PreprocessingRecord *Record;
+ PreprocessingRecord *Record = nullptr;
/// Cached tokens state.
- typedef SmallVector<Token, 1> CachedTokensTy;
+ using CachedTokensTy = SmallVector<Token, 1>;
/// \brief Cached tokens are stored here when we do backtracking or
/// lookahead. They are "lexed" by the CachingLex() method.
@@ -664,7 +754,7 @@ class Preprocessor {
///
/// If it points beyond the CachedTokens vector, it means that a normal
/// Lex() should be invoked.
- CachedTokensTy::size_type CachedLexPos;
+ CachedTokensTy::size_type CachedLexPos = 0;
/// \brief Stack of backtrack positions, allowing nested backtracks.
///
@@ -680,7 +770,7 @@ class Preprocessor {
/// MacroInfos are managed as a chain for easy disposal. This is the head
/// of that list.
- MacroInfoChain *MIChainHead;
+ MacroInfoChain *MIChainHead = nullptr;
void updateOutOfDateIdentifier(IdentifierInfo &II) const;
@@ -853,7 +943,7 @@ public:
MacroDefinition getMacroDefinition(const IdentifierInfo *II) {
if (!II->hasMacroDefinition())
- return MacroDefinition();
+ return {};
MacroState &S = CurSubmoduleState->Macros[II];
auto *MD = S.getLatest();
@@ -867,7 +957,7 @@ public:
MacroDefinition getMacroDefinitionAtLoc(const IdentifierInfo *II,
SourceLocation Loc) {
if (!II->hadMacroDefinition())
- return MacroDefinition();
+ return {};
MacroState &S = CurSubmoduleState->Macros[II];
MacroDirective::DefInfo DI;
@@ -923,6 +1013,7 @@ public:
MacroInfo *MI) {
return appendDefMacroDirective(II, MI, MI->getDefinitionLoc());
}
+
/// \brief Set a MacroDirective that was loaded from a PCH file.
void setLoadedMacroDirective(IdentifierInfo *II, MacroDirective *ED,
MacroDirective *MD);
@@ -946,10 +1037,12 @@ public:
/// 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 MacroMap::const_iterator macro_iterator;
+ using macro_iterator = MacroMap::const_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));
@@ -963,6 +1056,7 @@ public:
ArrayRef<TokenValue> Tokens) const;
const std::string &getPredefines() const { return Predefines; }
+
/// \brief Set the predefines for this Preprocessor.
///
/// These predefines are automatically injected when parsing the main file.
@@ -1087,6 +1181,7 @@ public:
bool DisableMacroExpansion) {
EnterTokenStream(Toks.release(), NumToks, DisableMacroExpansion, true);
}
+
void EnterTokenStream(ArrayRef<Token> Toks, bool DisableMacroExpansion) {
EnterTokenStream(Toks.data(), Toks.size(), DisableMacroExpansion, false);
}
@@ -1605,7 +1700,6 @@ private:
llvm::DenseMap<IdentifierInfo*,unsigned> PoisonReasons;
public:
-
/// \brief Specifies the reason for poisoning an identifier.
///
/// If that identifier is accessed while poisoned, then this reason will be
@@ -1655,7 +1749,6 @@ public:
/// lex again.
bool HandleIdentifier(Token &Identifier);
-
/// \brief Callback invoked when the lexer hits the end of the current file.
///
/// This either returns the EOF token and returns true, or
@@ -1760,6 +1853,8 @@ public:
Module *LeaveSubmodule(bool ForPragma);
private:
+ friend void TokenLexer::ExpandFunctionArguments();
+
void PushIncludeMacroStack() {
assert(CurLexerKind != CLK_CachingLexer && "cannot push a caching lexer");
IncludeMacroStack.emplace_back(CurLexerKind, CurLexerSubmodule,
@@ -1818,7 +1913,6 @@ private:
///
/// Either returns a pointer to a MacroInfo object OR emits a diagnostic and
/// returns a nullptr if an invalid sequence of tokens is encountered.
-
MacroInfo *ReadOptionalMacroParameterListAndBody(
const Token &MacroNameTok, bool ImmediatelyAfterHeaderGuard);
@@ -1836,7 +1930,8 @@ private:
/// \p FoundElse is false, then \#else directives are ok, if not, then we have
/// already seen one so a \#else directive is a duplicate. When this returns,
/// the caller can lex the first valid token.
- void SkipExcludedConditionalBlock(SourceLocation IfTokenLoc,
+ void SkipExcludedConditionalBlock(SourceLocation HashTokenLoc,
+ SourceLocation IfTokenLoc,
bool FoundNonSkipPortion, bool FoundElse,
SourceLocation ElseLoc = SourceLocation());
@@ -1848,6 +1943,7 @@ private:
struct DirectiveEvalResult {
/// Whether the expression was evaluated as true or not.
bool Conditional;
+
/// True if the expression contained identifiers that were undefined.
bool IncludedUndefinedIds;
};
@@ -1877,8 +1973,8 @@ private:
/// from the end of the cache.
Token *cacheMacroExpandedTokens(TokenLexer *tokLexer,
ArrayRef<Token> tokens);
+
void removeCachedMacroExpandedTokensOfLastLexer();
- friend void TokenLexer::ExpandFunctionArguments();
/// Determine whether the next preprocessor token to be
/// lexed is a '('. If so, consume the token and return true, if not, this
@@ -1934,17 +2030,21 @@ private:
//===--------------------------------------------------------------------===//
// Caching stuff.
void CachingLex(Token &Result);
+
bool InCachingLexMode() const {
// If the Lexer pointers are 0 and IncludeMacroStack is empty, it means
// that we are past EOF, not that we are in CachingLex mode.
return !CurPPLexer && !CurTokenLexer && !CurPTHLexer &&
!IncludeMacroStack.empty();
}
+
void EnterCachingLexMode();
+
void ExitCachingLexMode() {
if (InCachingLexMode())
RemoveTopOfLexerStack();
}
+
const Token &PeekAhead(unsigned N);
void AnnotatePreviousCachedTokens(const Token &Tok);
@@ -2015,9 +2115,15 @@ public:
PreambleConditionalStack.setStack(s);
}
- void setReplayablePreambleConditionalStack(ArrayRef<PPConditionalInfo> s) {
+ void setReplayablePreambleConditionalStack(ArrayRef<PPConditionalInfo> s,
+ llvm::Optional<PreambleSkipInfo> SkipInfo) {
PreambleConditionalStack.startReplaying();
PreambleConditionalStack.setStack(s);
+ PreambleConditionalStack.SkipInfo = SkipInfo;
+ }
+
+ llvm::Optional<PreambleSkipInfo> getPreambleSkipInfo() const {
+ return PreambleConditionalStack.SkipInfo;
}
private:
@@ -2030,16 +2136,18 @@ private:
void HandleUndefDirective();
// Conditional Inclusion.
- void HandleIfdefDirective(Token &Tok, bool isIfndef,
- bool ReadAnyTokensBeforeDirective);
- void HandleIfDirective(Token &Tok, bool ReadAnyTokensBeforeDirective);
+ void HandleIfdefDirective(Token &Tok, const Token &HashToken,
+ bool isIfndef, bool ReadAnyTokensBeforeDirective);
+ void HandleIfDirective(Token &Tok, const Token &HashToken,
+ bool ReadAnyTokensBeforeDirective);
void HandleEndifDirective(Token &Tok);
- void HandleElseDirective(Token &Tok);
- void HandleElifDirective(Token &Tok);
+ void HandleElseDirective(Token &Tok, const Token &HashToken);
+ void HandleElifDirective(Token &Tok, const Token &HashToken);
// Pragmas.
void HandlePragmaDirective(SourceLocation IntroducerLoc,
PragmaIntroducerKind Introducer);
+
public:
void HandlePragmaOnce(Token &OnceTok);
void HandlePragmaMark();
@@ -2073,8 +2181,8 @@ public:
};
/// \brief Registry of pragma handlers added by plugins
-typedef llvm::Registry<PragmaHandler> PragmaHandlerRegistry;
+using PragmaHandlerRegistry = llvm::Registry<PragmaHandler>;
-} // end namespace clang
+} // namespace clang
-#endif
+#endif // LLVM_CLANG_LEX_PREPROCESSOR_H
diff --git a/include/clang/Lex/PreprocessorLexer.h b/include/clang/Lex/PreprocessorLexer.h
index 5c2e4d41454b..ff71d11b4511 100644
--- a/include/clang/Lex/PreprocessorLexer.h
+++ b/include/clang/Lex/PreprocessorLexer.h
@@ -1,4 +1,4 @@
-//===--- PreprocessorLexer.h - C Language Family Lexer ----------*- C++ -*-===//
+//===- PreprocessorLexer.h - C Language Family Lexer ------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -6,10 +6,10 @@
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
-///
+//
/// \file
/// \brief Defines the PreprocessorLexer interface.
-///
+//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_LEX_PREPROCESSORLEXER_H
@@ -17,8 +17,10 @@
#include "clang/Lex/MultipleIncludeOpt.h"
#include "clang/Lex/Token.h"
+#include "clang/Basic/SourceLocation.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/SmallVector.h"
+#include <cassert>
namespace clang {
@@ -27,25 +29,29 @@ class Preprocessor;
class PreprocessorLexer {
virtual void anchor();
+
protected:
- Preprocessor *PP; // Preprocessor object controlling lexing.
+ friend class Preprocessor;
+
+ // Preprocessor object controlling lexing.
+ Preprocessor *PP = nullptr;
/// The SourceManager FileID corresponding to the file being lexed.
const FileID FID;
/// \brief Number of SLocEntries before lexing the file.
- unsigned InitialNumSLocEntries;
+ unsigned InitialNumSLocEntries = 0;
//===--------------------------------------------------------------------===//
// Context-specific lexing flags set by the preprocessor.
//===--------------------------------------------------------------------===//
/// \brief True when parsing \#XXX; turns '\\n' into a tok::eod token.
- bool ParsingPreprocessorDirective;
+ bool ParsingPreprocessorDirective = false;
/// \brief True after \#include; turns \<xx> into a tok::angle_string_literal
/// token.
- bool ParsingFilename;
+ bool ParsingFilename = false;
/// \brief True if in raw mode.
///
@@ -60,7 +66,7 @@ protected:
/// 5. No callbacks are made into the preprocessor.
///
/// Note that in raw mode that the PP pointer may be null.
- bool LexingRawMode;
+ bool LexingRawMode = false;
/// \brief A state machine that detects the \#ifndef-wrapping a file
/// idiom for the multiple-include optimization.
@@ -70,19 +76,9 @@ protected:
/// we are currently in.
SmallVector<PPConditionalInfo, 4> ConditionalStack;
- PreprocessorLexer(const PreprocessorLexer &) = delete;
- void operator=(const PreprocessorLexer &) = delete;
- friend class Preprocessor;
-
+ PreprocessorLexer() : FID() {}
PreprocessorLexer(Preprocessor *pp, FileID fid);
-
- PreprocessorLexer()
- : PP(nullptr), InitialNumSLocEntries(0),
- ParsingPreprocessorDirective(false),
- ParsingFilename(false),
- LexingRawMode(false) {}
-
- virtual ~PreprocessorLexer() {}
+ virtual ~PreprocessorLexer() = default;
virtual void IndirectLex(Token& Result) = 0;
@@ -128,6 +124,8 @@ protected:
unsigned getConditionalStackDepth() const { return ConditionalStack.size(); }
public:
+ PreprocessorLexer(const PreprocessorLexer &) = delete;
+ PreprocessorLexer &operator=(const PreprocessorLexer &) = delete;
//===--------------------------------------------------------------------===//
// Misc. lexing methods.
@@ -168,12 +166,13 @@ public:
/// \brief Iterator that traverses the current stack of preprocessor
/// conditional directives (\#if/\#ifdef/\#ifndef).
- typedef SmallVectorImpl<PPConditionalInfo>::const_iterator
- conditional_iterator;
+ using conditional_iterator =
+ SmallVectorImpl<PPConditionalInfo>::const_iterator;
conditional_iterator conditional_begin() const {
return ConditionalStack.begin();
}
+
conditional_iterator conditional_end() const {
return ConditionalStack.end();
}
@@ -184,6 +183,6 @@ public:
}
};
-} // end namespace clang
+} // namespace clang
-#endif
+#endif // LLVM_CLANG_LEX_PREPROCESSORLEXER_H
diff --git a/include/clang/Lex/PreprocessorOptions.h b/include/clang/Lex/PreprocessorOptions.h
index d91c665cf1dd..55fc305dc295 100644
--- a/include/clang/Lex/PreprocessorOptions.h
+++ b/include/clang/Lex/PreprocessorOptions.h
@@ -1,4 +1,4 @@
-//===--- PreprocessorOptions.h ----------------------------------*- C++ -*-===//
+//===- PreprocessorOptions.h ------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -10,30 +10,30 @@
#ifndef LLVM_CLANG_LEX_PREPROCESSOROPTIONS_H_
#define LLVM_CLANG_LEX_PREPROCESSOROPTIONS_H_
-#include "clang/Basic/SourceLocation.h"
-#include "llvm/ADT/IntrusiveRefCntPtr.h"
+#include "clang/Basic/LLVM.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/StringSet.h"
-#include <cassert>
+#include <memory>
#include <set>
#include <string>
#include <utility>
#include <vector>
namespace llvm {
- class MemoryBuffer;
-}
-namespace clang {
+class MemoryBuffer;
+
+} // namespace llvm
-class Preprocessor;
-class LangOptions;
+namespace clang {
/// \brief Enumerate the kinds of standard library that
enum ObjCXXARCStandardLibraryKind {
ARCXX_nolib,
+
/// \brief libc++
ARCXX_libcxx,
+
/// \brief libstdc++
ARCXX_libstdcxx
};
@@ -42,17 +42,17 @@ enum ObjCXXARCStandardLibraryKind {
/// used in preprocessor initialization to InitializePreprocessor().
class PreprocessorOptions {
public:
- std::vector<std::pair<std::string, bool/*isUndef*/> > Macros;
+ std::vector<std::pair<std::string, bool/*isUndef*/>> Macros;
std::vector<std::string> Includes;
std::vector<std::string> MacroIncludes;
/// \brief Initialize the preprocessor with the compiler and target specific
/// predefines.
- unsigned UsePredefines : 1;
+ bool UsePredefines = true;
/// \brief Whether we should maintain a detailed record of all macro
/// definitions and expansions.
- unsigned DetailedRecord : 1;
+ bool DetailedRecord = false;
/// The implicit PCH included at the start of the translation unit, or empty.
std::string ImplicitPCHInclude;
@@ -62,13 +62,13 @@ public:
/// \brief When true, disables most of the normal validation performed on
/// precompiled headers.
- bool DisablePCHValidation;
+ bool DisablePCHValidation = false;
/// \brief When true, a PCH with compiler errors will not be rejected.
- bool AllowPCHWithCompilerErrors;
+ bool AllowPCHWithCompilerErrors = false;
/// \brief Dump declarations that are deserialized from PCH, for testing.
- bool DumpDeserializedPCHDecls;
+ bool DumpDeserializedPCHDecls = false;
/// \brief This is a set of names for decls that we do not want to be
/// deserialized, and we emit an error if they are; for testing purposes.
@@ -86,7 +86,7 @@ public:
/// When the lexer is done, one of the things that need to be preserved is the
/// conditional #if stack, so the ASTWriter/ASTReader can save/restore it when
/// processing the rest of the file.
- bool GeneratePreamble;
+ bool GeneratePreamble = false;
/// The implicit PTH input included at the start of the translation unit, or
/// empty.
@@ -107,7 +107,7 @@ public:
/// \brief True if the SourceManager should report the original file name for
/// contents of files that were remapped to other files. Defaults to true.
- bool RemappedFilesKeepOriginalName;
+ bool RemappedFilesKeepOriginalName = true;
/// \brief The set of file remappings, which take existing files on
/// the system (the first part of each pair) and gives them the
@@ -126,12 +126,12 @@ public:
/// This flag defaults to false; it can be set true only through direct
/// manipulation of the compiler invocation object, in cases where the
/// compiler invocation and its buffers will be reused.
- bool RetainRemappedFileBuffers;
+ bool RetainRemappedFileBuffers = false;
/// \brief The Objective-C++ ARC standard library that we should support,
/// by providing appropriate definitions to retrofit the standard library
/// with support for lifetime-qualified pointers.
- ObjCXXARCStandardLibraryKind ObjCXXARCStandardLibrary;
+ ObjCXXARCStandardLibraryKind ObjCXXARCStandardLibrary = ARCXX_nolib;
/// \brief Records the set of modules
class FailedModulesSet {
@@ -156,18 +156,11 @@ public:
std::shared_ptr<FailedModulesSet> FailedModules;
public:
- PreprocessorOptions() : UsePredefines(true), DetailedRecord(false),
- DisablePCHValidation(false),
- AllowPCHWithCompilerErrors(false),
- DumpDeserializedPCHDecls(false),
- PrecompiledPreambleBytes(0, true),
- GeneratePreamble(false),
- RemappedFilesKeepOriginalName(true),
- RetainRemappedFileBuffers(false),
- ObjCXXARCStandardLibrary(ARCXX_nolib) { }
+ PreprocessorOptions() : PrecompiledPreambleBytes(0, false) {}
void addMacroDef(StringRef Name) { Macros.emplace_back(Name, false); }
void addMacroUndef(StringRef Name) { Macros.emplace_back(Name, true); }
+
void addRemappedFile(StringRef From, StringRef To) {
RemappedFiles.emplace_back(From, To);
}
@@ -195,10 +188,10 @@ public:
LexEditorPlaceholders = true;
RetainRemappedFileBuffers = true;
PrecompiledPreambleBytes.first = 0;
- PrecompiledPreambleBytes.second = 0;
+ PrecompiledPreambleBytes.second = false;
}
};
-} // end namespace clang
+} // namespace clang
-#endif
+#endif // LLVM_CLANG_LEX_PREPROCESSOROPTIONS_H_
diff --git a/include/clang/Lex/TokenLexer.h b/include/clang/Lex/TokenLexer.h
index fdeed44d8f9b..b8b0beabf2ba 100644
--- a/include/clang/Lex/TokenLexer.h
+++ b/include/clang/Lex/TokenLexer.h
@@ -1,4 +1,4 @@
-//===--- TokenLexer.h - Lex from a token buffer -----------------*- C++ -*-===//
+//===- TokenLexer.h - Lex from a token buffer -------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -15,29 +15,31 @@
#define LLVM_CLANG_LEX_TOKENLEXER_H
#include "clang/Basic/SourceLocation.h"
+#include "llvm/ADT/ArrayRef.h"
namespace clang {
- class MacroInfo;
- class Preprocessor;
- class Token;
- class MacroArgs;
+
+class MacroArgs;
+class MacroInfo;
+class Preprocessor;
+class Token;
+class VAOptExpansionContext;
/// TokenLexer - This implements a lexer that returns tokens from a macro body
/// or token stream instead of lexing from a character buffer. This is used for
/// macro expansion and _Pragma handling, for example.
-///
class TokenLexer {
+ friend class Preprocessor;
+
/// Macro - The macro we are expanding from. This is null if expanding a
/// token stream.
- ///
- MacroInfo *Macro;
+ MacroInfo *Macro = nullptr;
/// ActualArgs - The actual arguments specified for a function-like macro, or
/// null. The TokenLexer owns the pointed-to object.
- MacroArgs *ActualArgs;
+ MacroArgs *ActualArgs = nullptr;
/// PP - The current preprocessor object we are expanding for.
- ///
Preprocessor &PP;
/// Tokens - This is the pointer to an array of tokens that the macro is
@@ -49,15 +51,12 @@ class TokenLexer {
/// Note that if it points into Preprocessor's cache buffer, the Preprocessor
/// may update the pointer as needed.
const Token *Tokens;
- friend class Preprocessor;
/// NumTokens - This is the length of the Tokens array.
- ///
unsigned NumTokens;
- /// CurToken - This is the next token that Lex will return.
- ///
- unsigned CurToken;
+ /// This is the index of the next token that Lex will return.
+ unsigned CurTokenIdx;
/// ExpandLocStart/End - The source location range where this macro was
/// expanded.
@@ -73,6 +72,7 @@ class TokenLexer {
/// \brief Location of the macro definition.
SourceLocation MacroDefStart;
+
/// \brief Length of the macro definition.
unsigned MacroDefLength;
@@ -99,8 +99,6 @@ class TokenLexer {
/// should not be subject to further macro expansion.
bool DisableMacroExpansion : 1;
- 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.
@@ -108,26 +106,30 @@ public:
/// identifier for an object-like macro.
TokenLexer(Token &Tok, SourceLocation ILEnd, MacroInfo *MI,
MacroArgs *ActualArgs, Preprocessor &pp)
- : Macro(nullptr), ActualArgs(nullptr), PP(pp), OwnsTokens(false) {
+ : PP(pp), OwnsTokens(false) {
Init(Tok, ILEnd, MI, ActualArgs);
}
- /// Init - Initialize this TokenLexer to expand from the specified macro
- /// with the specified argument information. Note that this ctor takes
- /// ownership of the ActualArgs pointer. ILEnd specifies the location of the
- /// ')' for a function-like macro or the identifier for an object-like macro.
- void Init(Token &Tok, SourceLocation ILEnd, MacroInfo *MI,
- MacroArgs *ActualArgs);
-
/// Create a TokenLexer for the specified token stream. If 'OwnsTokens' is
/// specified, this takes ownership of the tokens and delete[]'s them when
/// the token lexer is empty.
TokenLexer(const Token *TokArray, unsigned NumToks, bool DisableExpansion,
bool ownsTokens, Preprocessor &pp)
- : Macro(nullptr), ActualArgs(nullptr), PP(pp), OwnsTokens(false) {
+ : PP(pp), OwnsTokens(false) {
Init(TokArray, NumToks, DisableExpansion, ownsTokens);
}
+ TokenLexer(const TokenLexer &) = delete;
+ TokenLexer &operator=(const TokenLexer &) = delete;
+ ~TokenLexer() { destroy(); }
+
+ /// Init - Initialize this TokenLexer to expand from the specified macro
+ /// with the specified argument information. Note that this ctor takes
+ /// ownership of the ActualArgs pointer. ILEnd specifies the location of the
+ /// ')' for a function-like macro or the identifier for an object-like macro.
+ void Init(Token &Tok, SourceLocation ILEnd, MacroInfo *MI,
+ MacroArgs *ActualArgs);
+
/// Init - Initialize this TokenLexer with the specified token stream.
/// This does not take ownership of the specified token vector.
///
@@ -136,8 +138,6 @@ public:
void Init(const Token *TokArray, unsigned NumToks,
bool DisableMacroExpansion, bool OwnsTokens);
- ~TokenLexer() { destroy(); }
-
/// isNextTokenLParen - If the next token lexed will pop this macro off the
/// expansion stack, return 2. If the next unexpanded token is a '(', return
/// 1, otherwise return 0.
@@ -156,15 +156,54 @@ private:
/// isAtEnd - Return true if the next lex call will pop this macro off the
/// include stack.
bool isAtEnd() const {
- return CurToken == NumTokens;
+ return CurTokenIdx == NumTokens;
}
- /// PasteTokens - Tok is the LHS of a ## operator, and CurToken is the ##
- /// operator. Read the ## and RHS, and paste the LHS/RHS together. If there
- /// are is another ## after it, chomp it iteratively. Return the result as
- /// Tok. If this returns true, the caller should immediately return the
+ /// Concatenates the next (sub-)sequence of \p Tokens separated by '##'
+ /// starting with LHSTok - stopping when we encounter a token that is neither
+ /// '##' nor preceded by '##'. Places the result back into \p LHSTok and sets
+ /// \p CurIdx to point to the token following the last one that was pasted.
+ ///
+ /// Also performs the MSVC extension wide-literal token pasting involved with:
+ /// \code L #macro-arg. \endcode
+ ///
+ /// \param[in,out] LHSTok - Contains the token to the left of '##' in \p
+ /// Tokens upon entry and will contain the resulting concatenated Token upon
+ /// exit.
+ ///
+ /// \param[in] TokenStream - The stream of Tokens we are lexing from.
+ ///
+ /// \param[in,out] CurIdx - Upon entry, \pTokens[\pCurIdx] must equal '##'
+ /// (with the exception of the MSVC extension mentioned above). Upon exit, it
+ /// is set to the index of the token following the last token that was
+ /// concatenated together.
+ ///
+ /// \returns If this returns true, the caller should immediately return the
/// token.
- bool PasteTokens(Token &Tok);
+ bool pasteTokens(Token &LHSTok, ArrayRef<Token> TokenStream,
+ unsigned int &CurIdx);
+
+ /// Calls pasteTokens above, passing in the '*this' object's Tokens and
+ /// CurTokenIdx data members.
+ bool pasteTokens(Token &Tok);
+
+
+ /// Takes the tail sequence of tokens within ReplacementToks that represent
+ /// the just expanded __VA_OPT__ tokens (possibly zero tokens) and transforms
+ /// them into a string. \p VCtx is used to determine which token represents
+ /// the first __VA_OPT__ replacement token.
+ ///
+ /// \param[in,out] ReplacementToks - Contains the current Replacement Tokens
+ /// (prior to rescanning and token pasting), the tail end of which represents
+ /// the tokens just expanded through __VA_OPT__ processing. These (sub)
+ /// sequence of tokens are folded into one stringified token.
+ ///
+ /// \param[in] VCtx - contains relevent contextual information about the
+ /// state of the tokens around and including the __VA_OPT__ token, necessary
+ /// for stringification.
+ void stringifyVAOPTContents(SmallVectorImpl<Token> &ReplacementToks,
+ const VAOptExpansionContext &VCtx,
+ SourceLocation VAOPTClosingParenLoc);
/// Expand the arguments of a function-like macro so that we can quickly
/// return preexpanded tokens from Tokens.
@@ -200,6 +239,6 @@ private:
void PropagateLineStartLeadingSpaceInfo(Token &Result);
};
-} // end namespace clang
+} // namespace clang
-#endif
+#endif // LLVM_CLANG_LEX_TOKENLEXER_H
diff --git a/include/clang/Lex/VariadicMacroSupport.h b/include/clang/Lex/VariadicMacroSupport.h
new file mode 100644
index 000000000000..cebaf15187de
--- /dev/null
+++ b/include/clang/Lex/VariadicMacroSupport.h
@@ -0,0 +1,226 @@
+//===- VariadicMacroSupport.h - state machines and scope guards -*- 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 support types to help with preprocessing variadic macro
+// (i.e. macros that use: ellipses __VA_ARGS__ ) definitions and
+// expansions.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_LEX_VARIADICMACROSUPPORT_H
+#define LLVM_CLANG_LEX_VARIADICMACROSUPPORT_H
+
+#include "clang/Lex/Preprocessor.h"
+#include "llvm/ADT/SmallVector.h"
+
+namespace clang {
+ class Preprocessor;
+
+ /// An RAII class that tracks when the Preprocessor starts and stops lexing
+ /// the definition of a (ISO C/C++) variadic macro. As an example, this is
+ /// useful for unpoisoning and repoisoning certain identifiers (such as
+ /// __VA_ARGS__) that are only allowed in this context. Also, being a friend
+ /// of the Preprocessor class allows it to access PP's cached identifiers
+ /// directly (as opposed to performing a lookup each time).
+ class VariadicMacroScopeGuard {
+ const Preprocessor &PP;
+ IdentifierInfo *const Ident__VA_ARGS__;
+ IdentifierInfo *const Ident__VA_OPT__;
+
+ public:
+ VariadicMacroScopeGuard(const Preprocessor &P)
+ : PP(P), Ident__VA_ARGS__(PP.Ident__VA_ARGS__),
+ Ident__VA_OPT__(PP.Ident__VA_OPT__) {
+ assert(Ident__VA_ARGS__->isPoisoned() && "__VA_ARGS__ should be poisoned "
+ "outside an ISO C/C++ variadic "
+ "macro definition!");
+ assert(
+ !Ident__VA_OPT__ ||
+ (Ident__VA_OPT__->isPoisoned() && "__VA_OPT__ should be poisoned!"));
+ }
+
+ /// Client code should call this function just before the Preprocessor is
+ /// about to Lex tokens from the definition of a variadic (ISO C/C++) macro.
+ void enterScope() {
+ Ident__VA_ARGS__->setIsPoisoned(false);
+ if (Ident__VA_OPT__)
+ Ident__VA_OPT__->setIsPoisoned(false);
+ }
+
+ /// Client code should call this function as soon as the Preprocessor has
+ /// either completed lexing the macro's definition tokens, or an error
+ /// occured and the context is being exited. This function is idempotent
+ /// (might be explicitly called, and then reinvoked via the destructor).
+ void exitScope() {
+ Ident__VA_ARGS__->setIsPoisoned(true);
+ if (Ident__VA_OPT__)
+ Ident__VA_OPT__->setIsPoisoned(true);
+ }
+
+ ~VariadicMacroScopeGuard() { exitScope(); }
+ };
+
+ /// \brief A class for tracking whether we're inside a VA_OPT during a
+ /// traversal of the tokens of a variadic macro definition.
+ class VAOptDefinitionContext {
+ /// Contains all the locations of so far unmatched lparens.
+ SmallVector<SourceLocation, 8> UnmatchedOpeningParens;
+
+ const IdentifierInfo *const Ident__VA_OPT__;
+
+
+ public:
+ VAOptDefinitionContext(Preprocessor &PP)
+ : Ident__VA_OPT__(PP.Ident__VA_OPT__) {}
+
+ bool isVAOptToken(const Token &T) const {
+ return Ident__VA_OPT__ && T.getIdentifierInfo() == Ident__VA_OPT__;
+ }
+
+ /// Returns true if we have seen the __VA_OPT__ and '(' but before having
+ /// seen the matching ')'.
+ bool isInVAOpt() const { return UnmatchedOpeningParens.size(); }
+
+ /// Call this function as soon as you see __VA_OPT__ and '('.
+ void sawVAOptFollowedByOpeningParens(const SourceLocation LParenLoc) {
+ assert(!isInVAOpt() && "Must NOT be within VAOPT context to call this");
+ UnmatchedOpeningParens.push_back(LParenLoc);
+
+ }
+
+ SourceLocation getUnmatchedOpeningParenLoc() const {
+ assert(isInVAOpt() && "Must be within VAOPT context to call this");
+ return UnmatchedOpeningParens.back();
+ }
+
+ /// Call this function each time an rparen is seen. It returns true only if
+ /// the rparen that was just seen was the eventual (non-nested) closing
+ /// paren for VAOPT, and ejects us out of the VAOPT context.
+ bool sawClosingParen() {
+ assert(isInVAOpt() && "Must be within VAOPT context to call this");
+ UnmatchedOpeningParens.pop_back();
+ return !UnmatchedOpeningParens.size();
+ }
+
+ /// Call this function each time an lparen is seen.
+ void sawOpeningParen(SourceLocation LParenLoc) {
+ assert(isInVAOpt() && "Must be within VAOPT context to call this");
+ UnmatchedOpeningParens.push_back(LParenLoc);
+ }
+
+ };
+
+ /// \brief A class for tracking whether we're inside a VA_OPT during a
+ /// traversal of the tokens of a macro during macro expansion.
+ class VAOptExpansionContext : VAOptDefinitionContext {
+
+ Token SyntheticEOFToken;
+
+ // The (spelling) location of the current __VA_OPT__ in the replacement list
+ // of the function-like macro being expanded.
+ SourceLocation VAOptLoc;
+
+ // NumOfTokensPriorToVAOpt : when != -1, contains the index *of* the first
+ // token of the current VAOPT contents (so we know where to start eager
+ // token-pasting and stringification) *within* the substituted tokens of
+ // the function-like macro's new replacement list.
+ int NumOfTokensPriorToVAOpt = -1;
+
+ unsigned LeadingSpaceForStringifiedToken : 1;
+
+ unsigned StringifyBefore : 1;
+ unsigned CharifyBefore : 1;
+
+
+ bool hasStringifyBefore() const {
+ assert(!isReset() &&
+ "Must only be called if the state has not been reset");
+ return StringifyBefore;
+ }
+
+ bool isReset() const {
+ return NumOfTokensPriorToVAOpt == -1 ||
+ VAOptLoc.isInvalid();
+ }
+
+ public:
+ VAOptExpansionContext(Preprocessor &PP)
+ : VAOptDefinitionContext(PP), LeadingSpaceForStringifiedToken(false),
+ StringifyBefore(false), CharifyBefore(false) {
+ SyntheticEOFToken.startToken();
+ SyntheticEOFToken.setKind(tok::eof);
+ }
+
+ void reset() {
+ VAOptLoc = SourceLocation();
+ NumOfTokensPriorToVAOpt = -1;
+ LeadingSpaceForStringifiedToken = false;
+ StringifyBefore = false;
+ CharifyBefore = false;
+ }
+
+ const Token &getEOFTok() const { return SyntheticEOFToken; }
+
+ void sawHashOrHashAtBefore(const bool HasLeadingSpace,
+ const bool IsHashAt) {
+
+ StringifyBefore = !IsHashAt;
+ CharifyBefore = IsHashAt;
+ LeadingSpaceForStringifiedToken = HasLeadingSpace;
+ }
+
+
+
+ bool hasCharifyBefore() const {
+ assert(!isReset() &&
+ "Must only be called if the state has not been reset");
+ return CharifyBefore;
+ }
+ bool hasStringifyOrCharifyBefore() const {
+ return hasStringifyBefore() || hasCharifyBefore();
+ }
+
+ unsigned int getNumberOfTokensPriorToVAOpt() const {
+ assert(!isReset() &&
+ "Must only be called if the state has not been reset");
+ return NumOfTokensPriorToVAOpt;
+ }
+
+ bool getLeadingSpaceForStringifiedToken() const {
+ assert(hasStringifyBefore() &&
+ "Must only be called if this has been marked for stringification");
+ return LeadingSpaceForStringifiedToken;
+ }
+
+ void sawVAOptFollowedByOpeningParens(const SourceLocation VAOptLoc,
+ const unsigned int NumPriorTokens) {
+ assert(VAOptLoc.isFileID() && "Must not come from a macro expansion");
+ assert(isReset() && "Must only be called if the state has been reset");
+ VAOptDefinitionContext::sawVAOptFollowedByOpeningParens(SourceLocation());
+ this->VAOptLoc = VAOptLoc;
+ NumOfTokensPriorToVAOpt = NumPriorTokens;
+ assert(NumOfTokensPriorToVAOpt > -1 &&
+ "Too many prior tokens");
+ }
+
+ SourceLocation getVAOptLoc() const {
+ assert(!isReset() &&
+ "Must only be called if the state has not been reset");
+ assert(VAOptLoc.isValid() && "__VA_OPT__ location must be valid");
+ return VAOptLoc;
+ }
+ using VAOptDefinitionContext::isVAOptToken;
+ using VAOptDefinitionContext::isInVAOpt;
+ using VAOptDefinitionContext::sawClosingParen;
+ using VAOptDefinitionContext::sawOpeningParen;
+
+ };
+} // end namespace clang
+
+#endif