summaryrefslogtreecommitdiff
path: root/include/clang/Lex
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2012-04-14 14:01:31 +0000
committerDimitry Andric <dim@FreeBSD.org>2012-04-14 14:01:31 +0000
commitdbe13110f59f48b4dbb7552b3ac2935acdeece7f (patch)
treebe1815eb79b42ff482a8562b13c2dcbf0c5dcbee /include/clang/Lex
parent9da628931ebf2609493570f87824ca22402cc65f (diff)
downloadsrc-test2-dbe13110f59f48b4dbb7552b3ac2935acdeece7f.tar.gz
src-test2-dbe13110f59f48b4dbb7552b3ac2935acdeece7f.zip
Notes
Diffstat (limited to 'include/clang/Lex')
-rw-r--r--include/clang/Lex/DirectoryLookup.h21
-rw-r--r--include/clang/Lex/ExternalPreprocessorSource.h3
-rw-r--r--include/clang/Lex/HeaderSearch.h229
-rw-r--r--include/clang/Lex/LexDiagnostic.h2
-rw-r--r--include/clang/Lex/Lexer.h75
-rw-r--r--include/clang/Lex/LiteralSupport.h54
-rw-r--r--include/clang/Lex/MacroInfo.h25
-rw-r--r--include/clang/Lex/ModuleLoader.h32
-rw-r--r--include/clang/Lex/ModuleMap.h237
-rw-r--r--include/clang/Lex/PPCallbacks.h89
-rw-r--r--include/clang/Lex/PreprocessingRecord.h111
-rw-r--r--include/clang/Lex/Preprocessor.h210
-rw-r--r--include/clang/Lex/PreprocessorLexer.h1
-rw-r--r--include/clang/Lex/Token.h6
14 files changed, 892 insertions, 203 deletions
diff --git a/include/clang/Lex/DirectoryLookup.h b/include/clang/Lex/DirectoryLookup.h
index f7da61b0ed71..95f0d2735093 100644
--- a/include/clang/Lex/DirectoryLookup.h
+++ b/include/clang/Lex/DirectoryLookup.h
@@ -22,7 +22,8 @@ class HeaderMap;
class DirectoryEntry;
class FileEntry;
class HeaderSearch;
-
+class Module;
+
/// DirectoryLookup - This class represents one entry in the search list that
/// specifies the search order for directories in #include directives. It
/// represents either a directory, a framework, or a headermap.
@@ -141,24 +142,26 @@ public:
/// SearchPath at which the file was found. This only differs from the
/// Filename for framework includes.
///
- /// \param BuildingModule The name of the module we're currently building.
- ///
/// \param SuggestedModule If non-null, and the file found is semantically
- /// part of a known module, this will be set to the name of the module that
- /// could be imported instead of preprocessing/parsing the file found.
+ /// part of a known module, this will be set to the module that should
+ /// be imported instead of preprocessing/parsing the file found.
+ ///
+ /// \param InUserSpecifiedSystemHeader [out] If the file is found, set to true
+ /// if the file is located in a framework that has been user-specified to be
+ /// treated as a system framework.
const FileEntry *LookupFile(StringRef Filename, HeaderSearch &HS,
SmallVectorImpl<char> *SearchPath,
SmallVectorImpl<char> *RelativePath,
- StringRef BuildingModule,
- StringRef *SuggestedModule) const;
+ Module **SuggestedModule,
+ bool &InUserSpecifiedSystemHeader) const;
private:
const FileEntry *DoFrameworkLookup(
StringRef Filename, HeaderSearch &HS,
SmallVectorImpl<char> *SearchPath,
SmallVectorImpl<char> *RelativePath,
- StringRef BuildingModule,
- StringRef *SuggestedModule) const;
+ Module **SuggestedModule,
+ bool &InUserSpecifiedSystemHeader) const;
};
diff --git a/include/clang/Lex/ExternalPreprocessorSource.h b/include/clang/Lex/ExternalPreprocessorSource.h
index dbf738903371..f172b5c8d22d 100644
--- a/include/clang/Lex/ExternalPreprocessorSource.h
+++ b/include/clang/Lex/ExternalPreprocessorSource.h
@@ -30,6 +30,9 @@ public:
/// \brief Read the definition for the given macro.
virtual void LoadMacroDefinition(IdentifierInfo *II) = 0;
+
+ /// \brief Update an out-of-date identifier.
+ virtual void updateOutOfDateIdentifier(IdentifierInfo &II) = 0;
};
}
diff --git a/include/clang/Lex/HeaderSearch.h b/include/clang/Lex/HeaderSearch.h
index 84d59f793bbb..5128ce6c1144 100644
--- a/include/clang/Lex/HeaderSearch.h
+++ b/include/clang/Lex/HeaderSearch.h
@@ -15,13 +15,16 @@
#define LLVM_CLANG_LEX_HEADERSEARCH_H
#include "clang/Lex/DirectoryLookup.h"
+#include "clang/Lex/ModuleMap.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringSet.h"
#include "llvm/Support/Allocator.h"
+#include "llvm/ADT/OwningPtr.h"
#include <vector>
namespace clang {
-
+
+class DiagnosticsEngine;
class ExternalIdentifierLookup;
class FileEntry;
class FileManager;
@@ -117,7 +120,19 @@ public:
/// HeaderSearch - This class encapsulates the information needed to find the
/// file referenced by a #include or #include_next, (sub-)framework lookup, etc.
class HeaderSearch {
+ /// This structure is used to record entries in our framework cache.
+ struct FrameworkCacheEntry {
+ /// The directory entry which should be used for the cached framework.
+ const DirectoryEntry *Directory;
+
+ /// Whether this framework has been "user-specified" to be treated as if it
+ /// were a system framework (even if it was found outside a system framework
+ /// directory).
+ bool IsUserSpecifiedSystemFramework;
+ };
+
FileManager &FileMgr;
+ DiagnosticsEngine &Diags;
/// #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
@@ -132,9 +147,6 @@ class HeaderSearch {
/// \brief The path to the module cache.
std::string ModuleCachePath;
- /// \brief The name of the module we're building.
- std::string BuildingModule;
-
/// FileInfo - This contains all of the preprocessor-specific data about files
/// that are included. The vector is indexed by the FileEntry's UID.
///
@@ -149,16 +161,27 @@ class HeaderSearch {
llvm::StringMap<std::pair<unsigned, unsigned>, llvm::BumpPtrAllocator>
LookupFileCache;
-
/// FrameworkMap - This is a collection mapping a framework or subframework
/// name like "Carbon" to the Carbon.framework directory.
- llvm::StringMap<const DirectoryEntry *, llvm::BumpPtrAllocator>
- FrameworkMap;
+ llvm::StringMap<FrameworkCacheEntry, llvm::BumpPtrAllocator> FrameworkMap;
+
+ /// 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;
+ OwningPtr<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;
+ /// \brief The mapping between modules and headers.
+ ModuleMap ModMap;
+
+ /// \brief Describes whether a given directory has a module map in it.
+ llvm::DenseMap<const DirectoryEntry *, bool> DirectoryHasModuleMap;
+
/// \brief Uniqued set of framework names, which is used to track which
/// headers were included as framework headers.
llvm::StringSet<llvm::BumpPtrAllocator> FrameworkNames;
@@ -179,8 +202,12 @@ class HeaderSearch {
explicit HeaderSearch();
explicit HeaderSearch(const HeaderSearch&);
void operator=(const HeaderSearch&);
+
+ friend class DirectoryLookup;
+
public:
- HeaderSearch(FileManager &FM);
+ HeaderSearch(FileManager &FM, DiagnosticsEngine &Diags,
+ const LangOptions &LangOpts, const TargetInfo *Target);
~HeaderSearch();
FileManager &getFileMgr() const { return FileMgr; }
@@ -199,13 +226,51 @@ public:
//LookupFileCache.clear();
}
- /// \brief Set the path to the module cache and the name of the module
- /// we're building
- void configureModules(StringRef CachePath, StringRef BuildingModule) {
+ /// AddSearchPath - Add an additional search path.
+ void AddSearchPath(const DirectoryLookup &dir, bool isAngled) {
+ unsigned idx = isAngled ? SystemDirIdx : AngledDirIdx;
+ SearchDirs.insert(SearchDirs.begin() + idx, dir);
+ if (!isAngled)
+ AngledDirIdx++;
+ SystemDirIdx++;
+ }
+
+ /// HasIncludeAliasMap - Checks whether the map exists or not
+ bool HasIncludeAliasMap() const {
+ return IncludeAliases;
+ }
+
+ /// AddIncludeAlias - Map the source include name to the dest include name.
+ /// The Source should include the angle brackets or quotes, the dest
+ /// should not. This allows for distinction between <> and "" headers.
+ void AddIncludeAlias(StringRef Source, StringRef Dest) {
+ if (!IncludeAliases)
+ IncludeAliases.reset(new IncludeAliasMap);
+ (*IncludeAliases)[Source] = Dest;
+ }
+
+ /// MapHeaderToIncludeAlias - Maps one header file name to a different header
+ /// file name, for use with the include_alias pragma. Note that the source
+ /// file name should include the angle brackets or quotes. Returns StringRef
+ /// as null if the header cannot be mapped.
+ StringRef MapHeaderToIncludeAlias(StringRef Source) {
+ assert(IncludeAliases && "Trying to map headers when there's no map");
+
+ // Do any filename replacements before anything else
+ IncludeAliasMap::const_iterator Iter = IncludeAliases->find(Source);
+ if (Iter != IncludeAliases->end())
+ return Iter->second;
+ return StringRef();
+ }
+
+ /// \brief Set the path to the module cache.
+ void setModuleCachePath(StringRef CachePath) {
ModuleCachePath = CachePath;
- this->BuildingModule = BuildingModule;
}
+ /// \brief Retrieve the path to the module cache.
+ StringRef getModuleCachePath() const { return ModuleCachePath; }
+
/// ClearFileInfo - Forget everything we know about headers so far.
void ClearFileInfo() {
FileInfo.clear();
@@ -224,6 +289,10 @@ public:
ExternalSource = ES;
}
+ /// \brief Set the target information for the header search, if not
+ /// already known.
+ void setTarget(const TargetInfo &Target);
+
/// LookupFile - Given a "foo" or <foo> reference, look up the indicated file,
/// return null on failure.
///
@@ -247,15 +316,16 @@ public:
/// Filename for framework includes.
///
/// \param SuggestedModule If non-null, and the file found is semantically
- /// part of a known module, this will be set to the name of the module that
- /// could be imported instead of preprocessing/parsing the file found.
+ /// part of a known module, this will be set to the module that should
+ /// be imported instead of preprocessing/parsing the file found.
const FileEntry *LookupFile(StringRef Filename, bool isAngled,
const DirectoryLookup *FromDir,
const DirectoryLookup *&CurDir,
const FileEntry *CurFileEnt,
SmallVectorImpl<char> *SearchPath,
SmallVectorImpl<char> *RelativePath,
- StringRef *SuggestedModule);
+ Module **SuggestedModule,
+ bool SkipCache = false);
/// LookupSubframeworkHeader - Look up a subframework for the specified
/// #include file. For example, if #include'ing <HIToolbox/HIToolbox.h> from
@@ -271,7 +341,7 @@ public:
/// LookupFrameworkCache - Look up the specified framework name in our
/// framework cache, returning the DirectoryEntry it is in if we know,
/// otherwise, return null.
- const DirectoryEntry *&LookupFrameworkCache(StringRef FWName) {
+ FrameworkCacheEntry &LookupFrameworkCache(StringRef FWName) {
return FrameworkMap.GetOrCreateValue(FWName).getValue();
}
@@ -326,33 +396,96 @@ public:
/// FileEntry, uniquing them through the the 'HeaderMaps' datastructure.
const HeaderMap *CreateHeaderMap(const FileEntry *FE);
- /// \brief Search in the module cache path for a module with the given
- /// name.
+ /// \brief Retrieve the name of the module file that should be used to
+ /// load the given module.
///
- /// \param If non-NULL, will be set to the module file name we expected to
- /// find (regardless of whether it was actually found or not).
+ /// \param Module The module whose module file name will be returned.
///
- /// \param UmbrellaHeader If non-NULL, and no module was found in the module
- /// cache, this routine will search in the framework paths to determine
- /// whether a module can be built from an umbrella header. If so, the pointee
- /// will be set to the path of the umbrella header.
+ /// \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);
+
+ /// \brief Retrieve the name of the module file that should be used to
+ /// load a module with the given name.
+ ///
+ /// \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(StringRef ModuleName);
+
+ /// \brief Lookup a module Search for a module with the given name.
///
- /// \returns A file describing the named module, if available, or NULL to
- /// indicate that the module could not be found.
- const FileEntry *lookupModule(StringRef ModuleName,
- std::string *ModuleFileName = 0,
- std::string *UmbrellaHeader = 0);
+ /// \param ModuleName The name of the module we're looking for.
+ ///
+ /// \param AllowSearch Whether we are allowed to search in the various
+ /// search directories to produce a module definition. If not, this lookup
+ /// will only return an already-known module.
+ ///
+ /// \returns The module with the given name.
+ Module *lookupModule(StringRef ModuleName, bool AllowSearch = true);
void IncrementFrameworkLookupCount() { ++NumFrameworkLookups; }
- typedef std::vector<HeaderFileInfo>::const_iterator header_file_iterator;
- header_file_iterator header_file_begin() const { return FileInfo.begin(); }
- header_file_iterator header_file_end() const { return FileInfo.end(); }
+ /// \brief Determine whether there is a module map that may map the header
+ /// with the given file name to a (sub)module.
+ ///
+ /// \param Filename The name of the file.
+ ///
+ /// \param Root The "root" directory, at which we should stop looking for
+ /// module maps.
+ bool hasModuleMap(StringRef Filename, const DirectoryEntry *Root);
+
+ /// \brief Retrieve the module that corresponds to the given file, if any.
+ ///
+ /// \param File The header that we wish to map to a module.
+ Module *findModuleForHeader(const FileEntry *File);
+
+ /// \brief Read the contents of the given module map file.
+ ///
+ /// \param File The module map file.
+ ///
+ /// \param OnlyModule If non-NULL, this will receive the
+ ///
+ /// \returns true if an error occurred, false otherwise.
+ bool loadModuleMapFile(const FileEntry *File);
+
+ /// \brief Collect the set of all known, top-level modules.
+ ///
+ /// \param Modules Will be filled with the set of known, top-level modules.
+ void collectAllModules(llvm::SmallVectorImpl<Module *> &Modules);
+
+private:
+ /// \brief Retrieve a module with the given name, which may be part of the
+ /// given framework.
+ ///
+ /// \param Name The name of the module to retrieve.
+ ///
+ /// \param Dir The framework directory (e.g., ModuleName.framework).
+ ///
+ /// \param IsSystem Whether the framework directory is part of the system
+ /// frameworks.
+ ///
+ /// \returns The module, if found; otherwise, null.
+ Module *loadFrameworkModule(StringRef Name,
+ const DirectoryEntry *Dir,
+ bool IsSystem);
+
+public:
+ /// \brief Retrieve the module map.
+ ModuleMap &getModuleMap() { return ModMap; }
+
unsigned header_file_size() const { return FileInfo.size(); }
// Used by ASTReader.
void setHeaderFileInfoForUID(HeaderFileInfo HFI, unsigned UID);
+ /// getFileInfo - Return the HeaderFileInfo structure for the specified
+ /// FileEntry.
+ const HeaderFileInfo &getFileInfo(const FileEntry *FE) const {
+ return const_cast<HeaderSearch*>(this)->getFileInfo(FE);
+ }
+
// Used by external tools
typedef std::vector<DirectoryLookup>::const_iterator search_dir_iterator;
search_dir_iterator search_dir_begin() const { return SearchDirs.begin(); }
@@ -385,7 +518,39 @@ public:
size_t getTotalMemory() const;
+ static std::string NormalizeDashIncludePath(StringRef File,
+ FileManager &FileMgr);
+
private:
+ /// \brief Describes what happened when we tried to load a module map file.
+ 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
+ };
+
+ /// \brief Try to load the module map file in the given directory.
+ ///
+ /// \param DirName The name of the directory where we will look for a module
+ /// map file.
+ ///
+ /// \returns The result of attempting to load the module map file from the
+ /// named directory.
+ LoadModuleMapResult loadModuleMapFile(StringRef DirName);
+
+ /// \brief Try to load the module map file in the given directory.
+ ///
+ /// \param Dir The directory where we will look for a module map file.
+ ///
+ /// \returns The result of attempting to load the module map file from the
+ /// named directory.
+ LoadModuleMapResult loadModuleMapFile(const DirectoryEntry *Dir);
/// getFileInfo - Return the HeaderFileInfo structure for the specified
/// FileEntry.
diff --git a/include/clang/Lex/LexDiagnostic.h b/include/clang/Lex/LexDiagnostic.h
index f454e2309acb..41b93963a7ee 100644
--- a/include/clang/Lex/LexDiagnostic.h
+++ b/include/clang/Lex/LexDiagnostic.h
@@ -16,7 +16,7 @@ namespace clang {
namespace diag {
enum {
#define DIAG(ENUM,FLAGS,DEFAULT_MAPPING,DESC,GROUP,\
- SFINAE,ACCESS,NOWERROR,SHOWINSYSHEADER,CATEGORY,BRIEF,FULL) ENUM,
+ SFINAE,ACCESS,NOWERROR,SHOWINSYSHEADER,CATEGORY) ENUM,
#define LEXSTART
#include "clang/Basic/DiagnosticLexKinds.inc"
#undef DIAG
diff --git a/include/clang/Lex/Lexer.h b/include/clang/Lex/Lexer.h
index e01427f574d2..04bcead6d45e 100644
--- a/include/clang/Lex/Lexer.h
+++ b/include/clang/Lex/Lexer.h
@@ -44,12 +44,14 @@ enum ConflictMarkerKind {
/// 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 {
+ virtual void anchor();
+
//===--------------------------------------------------------------------===//
// 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 Features; // Features enabled by this language (cache).
+ LangOptions LangOpts; // LangOpts enabled by this language (cache).
bool Is_PragmaLexer; // True if lexer for _Pragma handling.
//===--------------------------------------------------------------------===//
@@ -97,14 +99,14 @@ public:
/// Lexer constructor - Create a new raw lexer object. This object is only
/// suitable for calls to 'LexRawToken'. This lexer assumes that the text
/// range will outlive it, so it doesn't take ownership of it.
- Lexer(SourceLocation FileLoc, const LangOptions &Features,
+ Lexer(SourceLocation FileLoc, const LangOptions &LangOpts,
const char *BufStart, const char *BufPtr, const char *BufEnd);
/// Lexer constructor - Create a new raw lexer object. This object is only
/// suitable for calls to 'LexRawToken'. This lexer assumes that the text
/// range will outlive it, so it doesn't take ownership of it.
Lexer(FileID FID, const llvm::MemoryBuffer *InputBuffer,
- const SourceManager &SM, const LangOptions &Features);
+ const SourceManager &SM, const LangOptions &LangOpts);
/// Create_PragmaLexer: Lexer constructor - Create a new lexer object for
/// _Pragma expansion. This has a variety of magic semantics that this method
@@ -115,9 +117,9 @@ public:
unsigned TokLen, Preprocessor &PP);
- /// getFeatures - Return the language features currently enabled. NOTE: this
- /// lexer modifies features as a file is parsed!
- const LangOptions &getFeatures() const { return Features; }
+ /// getLangOpts - Return the language features currently enabled.
+ /// NOTE: this lexer modifies features as a file is parsed!
+ const LangOptions &getLangOpts() const { return LangOpts; }
/// getFileLoc - Return the File Location for the file we are lexing out of.
/// The physical location encodes the location where the characters come from,
@@ -238,7 +240,7 @@ public:
/// if an internal buffer is returned.
static unsigned getSpelling(const Token &Tok, const char *&Buffer,
const SourceManager &SourceMgr,
- const LangOptions &Features,
+ const LangOptions &LangOpts,
bool *Invalid = 0);
/// getSpelling() - Return the 'spelling' of the Tok token. The spelling of a
@@ -248,7 +250,7 @@ public:
/// UCNs, etc.
static std::string getSpelling(const Token &Tok,
const SourceManager &SourceMgr,
- const LangOptions &Features,
+ const LangOptions &LangOpts,
bool *Invalid = 0);
/// getSpelling - This method is used to get the spelling of the
@@ -262,7 +264,7 @@ public:
static StringRef getSpelling(SourceLocation loc,
SmallVectorImpl<char> &buffer,
const SourceManager &SourceMgr,
- const LangOptions &Features,
+ const LangOptions &LangOpts,
bool *invalid = 0);
/// MeasureTokenLength - Relex the token at the specified location and return
@@ -288,7 +290,7 @@ public:
static SourceLocation AdvanceToTokenCharacter(SourceLocation TokStart,
unsigned Character,
const SourceManager &SM,
- const LangOptions &Features);
+ const LangOptions &LangOpts);
/// \brief Computes the source location just past the end of the
/// token at this source location.
@@ -307,19 +309,52 @@ public:
/// a source location pointing to the last character in the token, etc.
static SourceLocation getLocForEndOfToken(SourceLocation Loc, unsigned Offset,
const SourceManager &SM,
- const LangOptions &Features);
+ const LangOptions &LangOpts);
/// \brief Returns true if the given MacroID location points at the first
/// token of the macro expansion.
+ ///
+ /// \param MacroBegin If non-null and function returns true, it is set to
+ /// begin location of the macro.
static bool isAtStartOfMacroExpansion(SourceLocation loc,
- const SourceManager &SM,
- const LangOptions &LangOpts);
+ const SourceManager &SM,
+ const LangOptions &LangOpts,
+ SourceLocation *MacroBegin = 0);
/// \brief Returns true if the given MacroID location points at the last
/// token of the macro expansion.
+ ///
+ /// \param MacroBegin If non-null and function returns true, it is set to
+ /// end location of the macro.
static bool isAtEndOfMacroExpansion(SourceLocation loc,
- const SourceManager &SM,
- const LangOptions &LangOpts);
+ const SourceManager &SM,
+ const LangOptions &LangOpts,
+ SourceLocation *MacroEnd = 0);
+
+ /// \brief Accepts a range and returns a character range with file locations.
+ ///
+ /// Returns a null range if a part of the range resides inside a macro
+ /// expansion or the range does not reside on the same FileID.
+ static CharSourceRange makeFileCharRange(CharSourceRange Range,
+ const SourceManager &SM,
+ const LangOptions &LangOpts);
+
+ /// \brief Returns a string for the source that the range encompasses.
+ static StringRef getSourceText(CharSourceRange Range,
+ const SourceManager &SM,
+ const LangOptions &LangOpts,
+ bool *Invalid = 0);
+
+ /// \brief Retrieve the name of the immediate macro expansion.
+ ///
+ /// This routine starts from a source location, and finds the name of the macro
+ /// responsible for its immediate expansion. It looks through any intervening
+ /// macro argument expansions to compute this. It returns a StringRef which
+ /// refers to the SourceManager-owned buffer of the source where that macro
+ /// name is spelled. Thus, the result shouldn't out-live that SourceManager.
+ static StringRef getImmediateMacroName(SourceLocation Loc,
+ const SourceManager &SM,
+ const LangOptions &LangOpts);
/// \brief Compute the preamble of the given file.
///
@@ -337,7 +372,7 @@ public:
/// 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(const llvm::MemoryBuffer *Buffer, const LangOptions &Features,
+ ComputePreamble(const llvm::MemoryBuffer *Buffer, const LangOptions &LangOpts,
unsigned MaxLines = 0);
//===--------------------------------------------------------------------===//
@@ -451,7 +486,7 @@ public:
/// getCharAndSizeNoWarn - Like the getCharAndSize method, but does not ever
/// emit a warning.
static inline char getCharAndSizeNoWarn(const char *Ptr, unsigned &Size,
- const LangOptions &Features) {
+ const LangOptions &LangOpts) {
// If this is not a trigraph and not a UCN or escaped newline, return
// quickly.
if (isObviouslySimpleCharacter(Ptr[0])) {
@@ -460,7 +495,7 @@ public:
}
Size = 0;
- return getCharAndSizeSlowNoWarn(Ptr, Size, Features);
+ return getCharAndSizeSlowNoWarn(Ptr, Size, LangOpts);
}
/// getEscapedNewLineSize - Return the size of the specified escaped newline,
@@ -489,12 +524,14 @@ private:
/// getCharAndSizeSlowNoWarn - Same as getCharAndSizeSlow, but never emits a
/// diagnostic.
static char getCharAndSizeSlowNoWarn(const char *Ptr, unsigned &Size,
- const LangOptions &Features);
+ const LangOptions &LangOpts);
//===--------------------------------------------------------------------===//
// Other lexer functions.
void SkipBytes(unsigned Bytes, bool StartOfLine);
+
+ const char *LexUDSuffix(Token &Result, const char *CurPtr);
// Helper functions to lex the remainder of a token of the specific type.
void LexIdentifier (Token &Result, const char *CurPtr);
diff --git a/include/clang/Lex/LiteralSupport.h b/include/clang/Lex/LiteralSupport.h
index b33092c753a8..7e7f82f05fa1 100644
--- a/include/clang/Lex/LiteralSupport.h
+++ b/include/clang/Lex/LiteralSupport.h
@@ -45,7 +45,7 @@ class NumericLiteralParser {
unsigned radix;
- bool saw_exponent, saw_period;
+ bool saw_exponent, saw_period, saw_ud_suffix;
public:
NumericLiteralParser(const char *begin, const char *end,
@@ -64,8 +64,17 @@ public:
bool isFloatingLiteral() const {
return saw_period || saw_exponent;
}
- bool hasSuffix() const {
- return SuffixBegin != ThisTokEnd;
+
+ bool hasUDSuffix() const {
+ return saw_ud_suffix;
+ }
+ StringRef getUDSuffix() const {
+ assert(saw_ud_suffix);
+ return StringRef(SuffixBegin, ThisTokEnd - SuffixBegin);
+ }
+ unsigned getUDSuffixOffset() const {
+ assert(saw_ud_suffix);
+ return SuffixBegin - ThisTokBegin;
}
unsigned getRadix() const { return radix; }
@@ -128,6 +137,8 @@ class CharLiteralParser {
tok::TokenKind Kind;
bool IsMultiChar;
bool HadError;
+ SmallString<32> UDSuffixBuf;
+ unsigned UDSuffixOffset;
public:
CharLiteralParser(const char *begin, const char *end,
SourceLocation Loc, Preprocessor &PP,
@@ -140,6 +151,11 @@ public:
bool isUTF32() const { return Kind == tok::utf32_char_constant; }
bool isMultiChar() const { return IsMultiChar; }
uint64_t getValue() const { return Value; }
+ StringRef getUDSuffix() const { return UDSuffixBuf; }
+ unsigned getUDSuffixOffset() const {
+ assert(!UDSuffixBuf.empty() && "no ud-suffix");
+ return UDSuffixOffset;
+ }
};
/// StringLiteralParser - This decodes string escape characters and performs
@@ -155,8 +171,11 @@ class StringLiteralParser {
unsigned SizeBound;
unsigned CharByteWidth;
tok::TokenKind Kind;
- llvm::SmallString<512> ResultBuf;
+ SmallString<512> ResultBuf;
char *ResultPtr; // cursor
+ SmallString<32> UDSuffixBuf;
+ unsigned UDSuffixToken;
+ unsigned UDSuffixOffset;
public:
StringLiteralParser(const Token *StringToks, unsigned NumStringToks,
Preprocessor &PP, bool Complain = true);
@@ -189,15 +208,30 @@ public:
/// checking of the string literal and emit errors and warnings.
unsigned getOffsetOfStringByte(const Token &TheTok, unsigned ByteNo) const;
- bool isAscii() { return Kind == tok::string_literal; }
- bool isWide() { return Kind == tok::wide_string_literal; }
- bool isUTF8() { return Kind == tok::utf8_string_literal; }
- bool isUTF16() { return Kind == tok::utf16_string_literal; }
- bool isUTF32() { return Kind == tok::utf32_string_literal; }
+ bool isAscii() const { return Kind == tok::string_literal; }
+ bool isWide() const { return Kind == tok::wide_string_literal; }
+ bool isUTF8() const { return Kind == tok::utf8_string_literal; }
+ bool isUTF16() const { return Kind == tok::utf16_string_literal; }
+ bool isUTF32() const { return Kind == tok::utf32_string_literal; }
+ bool isPascal() const { return Pascal; }
+
+ StringRef getUDSuffix() const { return UDSuffixBuf; }
+
+ /// Get the index of a token containing a ud-suffix.
+ unsigned getUDSuffixToken() const {
+ assert(!UDSuffixBuf.empty() && "no ud-suffix");
+ return UDSuffixToken;
+ }
+ /// Get the spelling offset of the first byte of the ud-suffix.
+ unsigned getUDSuffixOffset() const {
+ assert(!UDSuffixBuf.empty() && "no ud-suffix");
+ return UDSuffixOffset;
+ }
private:
void init(const Token *StringToks, unsigned NumStringToks);
- void CopyStringFragment(StringRef Fragment);
+ bool CopyStringFragment(StringRef Fragment);
+ bool DiagnoseBadString(const Token& Tok);
};
} // end namespace clang
diff --git a/include/clang/Lex/MacroInfo.h b/include/clang/Lex/MacroInfo.h
index b381e0f25f41..8775d39fe8dd 100644
--- a/include/clang/Lex/MacroInfo.h
+++ b/include/clang/Lex/MacroInfo.h
@@ -39,10 +39,11 @@ class MacroInfo {
IdentifierInfo **ArgumentList;
unsigned NumArguments;
- /// \brief The location at which this macro was exported from its module.
+ /// \brief The location at which this macro was either explicitly exported
+ /// from its module or marked as private.
///
- /// If invalid, this macro has not been explicitly exported.
- SourceLocation ExportLocation;
+ /// If invalid, this macro has not been explicitly given any visibility.
+ SourceLocation VisibilityLocation;
/// ReplacementTokens - This is the list of tokens that the macro is defined
/// to.
@@ -97,6 +98,9 @@ private:
/// \brief Must warn if the macro is unused at the end of translation unit.
bool IsWarnIfUnused : 1;
+ /// \brief Whether the macro has public (when described in a module).
+ bool IsPublic : 1;
+
~MacroInfo() {
assert(ArgumentList == 0 && "Didn't call destroy before dtor!");
}
@@ -279,17 +283,18 @@ public:
}
/// \brief Set the export location for this macro.
- void setExportLocation(SourceLocation ExportLoc) {
- ExportLocation = ExportLoc;
+ void setVisibility(bool Public, SourceLocation Loc) {
+ VisibilityLocation = Loc;
+ IsPublic = Public;
}
- /// \brief Determine whether this macro was explicitly exported from its
+ /// \brief Determine whether this macro is part of the public API of its
/// module.
- bool isExported() const { return ExportLocation.isValid(); }
+ bool isPublic() const { return IsPublic; }
- /// \brief Determine the location where this macro was explicitly exported
- /// from its module.
- SourceLocation getExportLocation() { return ExportLocation; }
+ /// \brief Determine the location where this macro was explicitly made
+ /// public or private within its module.
+ SourceLocation getVisibilityLocation() { return VisibilityLocation; }
private:
unsigned getDefinitionLengthSlow(SourceManager &SM) const;
diff --git a/include/clang/Lex/ModuleLoader.h b/include/clang/Lex/ModuleLoader.h
index 72ec0e3ebc9f..36d03c0aa2a3 100644
--- a/include/clang/Lex/ModuleLoader.h
+++ b/include/clang/Lex/ModuleLoader.h
@@ -14,15 +14,18 @@
#ifndef LLVM_CLANG_LEX_MODULE_LOADER_H
#define LLVM_CLANG_LEX_MODULE_LOADER_H
+#include "clang/Basic/Module.h"
#include "clang/Basic/SourceLocation.h"
+#include "llvm/ADT/ArrayRef.h"
namespace clang {
class IdentifierInfo;
-/// \brief An opaque key that is used to describe the module and can be
-/// interpreted by the module loader itself.
-typedef void *ModuleKey;
+/// \brief A sequence of identifier/location pairs used to describe a particular
+/// module or submodule, e.g., std.vector.
+typedef llvm::ArrayRef<std::pair<IdentifierInfo*, SourceLocation> >
+ ModuleIdPath;
/// \brief Abstract interface for a module loader.
///
@@ -39,15 +42,22 @@ public:
/// parameters.
///
/// \param ImportLoc The location of the 'import' keyword.
- /// \param ModuleName The name of the module to be loaded.
- /// \param ModuleNameLoc The location of the module name.
///
- /// \returns If successful, a non-NULL module key describing this module.
- /// Otherwise, returns NULL to indicate that the module could not be
- /// loaded.
- virtual ModuleKey loadModule(SourceLocation ImportLoc,
- IdentifierInfo &ModuleName,
- SourceLocation ModuleNameLoc) = 0;
+ /// \param Path The identifiers (and their locations) of the module
+ /// "path", e.g., "std.vector" would be split into "std" and "vector".
+ ///
+ /// \param Visibility The visibility provided for the names in the loaded
+ /// module.
+ ///
+ /// \param IsInclusionDirective Indicates that this module is being loaded
+ /// implicitly, due to the presence of an inclusion directive. Otherwise,
+ /// it is being loaded due to an import declaration.
+ ///
+ /// \returns If successful, returns the loaded module. Otherwise, returns
+ /// NULL to indicate that the module could not be loaded.
+ virtual Module *loadModule(SourceLocation ImportLoc, ModuleIdPath Path,
+ Module::NameVisibilityKind Visibility,
+ bool IsInclusionDirective) = 0;
};
}
diff --git a/include/clang/Lex/ModuleMap.h b/include/clang/Lex/ModuleMap.h
new file mode 100644
index 000000000000..4ebb1d42bf3d
--- /dev/null
+++ b/include/clang/Lex/ModuleMap.h
@@ -0,0 +1,237 @@
+//===--- ModuleMap.h - Describe the layout of modules -----------*- 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 the ModuleMap interface, which describes the layout of a
+// module as it relates to headers.
+//
+//===----------------------------------------------------------------------===//
+
+
+#ifndef LLVM_CLANG_LEX_MODULEMAP_H
+#define LLVM_CLANG_LEX_MODULEMAP_H
+
+#include "clang/Basic/LangOptions.h"
+#include "clang/Basic/Module.h"
+#include "clang/Basic/SourceManager.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/IntrusiveRefCntPtr.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/StringMap.h"
+#include <string>
+
+namespace clang {
+
+class DirectoryEntry;
+class FileEntry;
+class FileManager;
+class DiagnosticConsumer;
+class DiagnosticsEngine;
+class ModuleMapParser;
+
+class ModuleMap {
+ SourceManager *SourceMgr;
+ IntrusiveRefCntPtr<DiagnosticsEngine> Diags;
+ const LangOptions &LangOpts;
+ const TargetInfo *Target;
+
+ /// \brief The directory used for Clang-supplied, builtin include headers,
+ /// such as "stdint.h".
+ const DirectoryEntry *BuiltinIncludeDir;
+
+ /// \brief Language options used to parse the module map itself.
+ ///
+ /// These are always simple C language options.
+ LangOptions MMapLangOpts;
+
+ /// \brief The top-level modules that are known.
+ llvm::StringMap<Module *> Modules;
+
+ /// \brief Mapping from each header to the module that owns the contents of the
+ /// that header.
+ llvm::DenseMap<const FileEntry *, Module *> Headers;
+
+ /// \brief Mapping from directories with umbrella headers to the module
+ /// that is generated from the umbrella header.
+ ///
+ /// This mapping is used to map headers that haven't explicitly been named
+ /// in the module map over to the module that includes them via its umbrella
+ /// header.
+ llvm::DenseMap<const DirectoryEntry *, Module *> UmbrellaDirs;
+
+ friend class ModuleMapParser;
+
+ /// \brief Resolve the given export declaration into an actual export
+ /// declaration.
+ ///
+ /// \param Mod The module in which we're resolving the export declaration.
+ ///
+ /// \param Unresolved The export declaration to resolve.
+ ///
+ /// \param Complain Whether this routine should complain about unresolvable
+ /// exports.
+ ///
+ /// \returns The resolved export declaration, which will have a NULL pointer
+ /// if the export could not be resolved.
+ Module::ExportDecl
+ resolveExport(Module *Mod, const Module::UnresolvedExportDecl &Unresolved,
+ bool Complain);
+
+public:
+ /// \brief Construct a new module map.
+ ///
+ /// \param FileMgr The file manager used to find module files and headers.
+ /// This file manager should be shared with the header-search mechanism, since
+ /// they will refer to the same headers.
+ ///
+ /// \param DC A diagnostic consumer that will be cloned for use in generating
+ /// diagnostics.
+ ///
+ /// \param LangOpts Language options for this translation unit.
+ ///
+ /// \param Target The target for this translation unit.
+ ModuleMap(FileManager &FileMgr, const DiagnosticConsumer &DC,
+ const LangOptions &LangOpts, const TargetInfo *Target);
+
+ /// \brief Destroy the module map.
+ ///
+ ~ModuleMap();
+
+ /// \brief Set the target information.
+ void setTarget(const TargetInfo &Target);
+
+ /// \brief Set the directory that contains Clang-supplied include
+ /// files, such as our stdarg.h or tgmath.h.
+ void setBuiltinIncludeDir(const DirectoryEntry *Dir) {
+ BuiltinIncludeDir = Dir;
+ }
+
+ /// \brief Retrieve the module that owns the given header file, if any.
+ ///
+ /// \param File The header file that is likely to be included.
+ ///
+ /// \returns The module that owns the given header file, or null to indicate
+ /// that no module owns this header file.
+ Module *findModuleForHeader(const FileEntry *File);
+
+ /// \brief Determine whether the given header is part of a module
+ /// marked 'unavailable'.
+ bool isHeaderInUnavailableModule(const FileEntry *Header);
+
+ /// \brief Retrieve a module with the given name.
+ ///
+ /// \param The name of the module to look up.
+ ///
+ /// \returns The named module, if known; otherwise, returns null.
+ Module *findModule(StringRef Name);
+
+ /// \brief Retrieve a module with the given name using lexical name lookup,
+ /// starting at the given context.
+ ///
+ /// \param The name of the module to look up.
+ ///
+ /// \param Context The module context, from which we will perform lexical
+ /// name lookup.
+ ///
+ /// \returns The named module, if known; otherwise, returns null.
+ Module *lookupModuleUnqualified(StringRef Name, Module *Context);
+
+ /// \brief Retrieve a module with the given name within the given context,
+ /// using direct (qualified) name lookup.
+ ///
+ /// \param The name of the module to look up.
+ ///
+ /// \param Context The module for which we will look for a submodule. If
+ /// null, we will look for a top-level module.
+ ///
+ /// \returns The named submodule, if known; otherwose, returns null.
+ Module *lookupModuleQualified(StringRef Name, Module *Context);
+
+ /// \brief Find a new module or submodule, or create it if it does not already
+ /// exist.
+ ///
+ /// \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.
+ ///
+ /// \param IsFramework Whether this is a framework module.
+ ///
+ /// \param IsExplicit Whether this is an explicit submodule.
+ ///
+ /// \returns The found or newly-created module, along with a boolean value
+ /// that will be true if the module is newly-created.
+ std::pair<Module *, bool> findOrCreateModule(StringRef Name, Module *Parent,
+ bool IsFramework,
+ bool IsExplicit);
+
+ /// \brief Infer the contents of a framework module map from the given
+ /// framework directory.
+ Module *inferFrameworkModule(StringRef ModuleName,
+ const DirectoryEntry *FrameworkDir,
+ bool IsSystem, Module *Parent);
+
+ /// \brief Retrieve the module map file containing the definition of the given
+ /// module.
+ ///
+ /// \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.
+ const FileEntry *getContainingModuleMapFile(Module *Module);
+
+ /// \brief Resolve all of the unresolved exports in the given module.
+ ///
+ /// \param Mod The module whose exports should be resolved.
+ ///
+ /// \param Complain Whether to emit diagnostics for failures.
+ ///
+ /// \returns true if any errors were encountered while resolving exports,
+ /// false otherwise.
+ bool resolveExports(Module *Mod, bool Complain);
+
+ /// \brief Infers the (sub)module based on the given source location and
+ /// source manager.
+ ///
+ /// \param Loc The location within the source that we are querying, along
+ /// with its source manager.
+ ///
+ /// \returns The module that owns this source location, or null if no
+ /// module owns this source location.
+ Module *inferModuleFromLocation(FullSourceLoc Loc);
+
+ /// \brief Sets the umbrella header of the given module to the given
+ /// header.
+ void setUmbrellaHeader(Module *Mod, const FileEntry *UmbrellaHeader);
+
+ /// \brief Sets the umbrella directory of the given module to the given
+ /// directory.
+ void setUmbrellaDir(Module *Mod, const DirectoryEntry *UmbrellaDir);
+
+ /// \brief Adds this header to the given module.
+ void addHeader(Module *Mod, const FileEntry *Header);
+
+ /// \brief Parse the given module map file, and record any modules we
+ /// encounter.
+ ///
+ /// \param File The file to be parsed.
+ ///
+ /// \returns true if an error occurred, false otherwise.
+ bool parseModuleMapFile(const FileEntry *File);
+
+ /// \brief Dump the contents of the module map, for debugging purposes.
+ void dump();
+
+ typedef llvm::StringMap<Module *>::const_iterator module_iterator;
+ module_iterator module_begin() const { return Modules.begin(); }
+ module_iterator module_end() const { return Modules.end(); }
+};
+
+}
+#endif
diff --git a/include/clang/Lex/PPCallbacks.h b/include/clang/Lex/PPCallbacks.h
index 1fc1a05db646..33558c8dfdc9 100644
--- a/include/clang/Lex/PPCallbacks.h
+++ b/include/clang/Lex/PPCallbacks.h
@@ -58,6 +58,23 @@ public:
SrcMgr::CharacteristicKind FileType) {
}
+ /// FileNotFound - This callback is invoked whenever an inclusion directive
+ /// results in a file-not-found error.
+ ///
+ /// \param FileName The name of the file being included, as written in the
+ /// source code.
+ ///
+ /// \param RecoveryPath If this client indicates that it can recover from
+ /// this missing file, the client should set this as an additional header
+ /// search patch.
+ ///
+ /// \returns true to indicate that the preprocessor should attempt to recover
+ /// by adding \p RecoveryPath as a header search path.
+ virtual bool FileNotFound(StringRef FileName,
+ SmallVectorImpl<char> &RecoveryPath) {
+ return false;
+ }
+
/// \brief This callback is invoked whenever an inclusion directive of
/// any kind (\c #include, \c #import, etc.) has been processed, regardless
/// of whether the inclusion will actually result in an inclusion.
@@ -173,40 +190,49 @@ public:
}
/// If -- This hook is called whenever an #if is seen.
- /// \param Range The SourceRange of the expression being tested.
+ /// \param Loc the source location of the directive.
+ /// \param ConditionRange The SourceRange of the expression being tested.
// FIXME: better to pass in a list (or tree!) of Tokens.
- virtual void If(SourceRange Range) {
+ virtual void If(SourceLocation Loc, SourceRange ConditionRange) {
}
/// Elif -- This hook is called whenever an #elif is seen.
- /// \param Range The SourceRange of the expression being tested.
+ /// \param Loc the source location of the directive.
+ /// \param ConditionRange The SourceRange of the expression being tested.
+ /// \param IfLoc the source location of the #if/#ifdef/#ifndef directive.
// FIXME: better to pass in a list (or tree!) of Tokens.
- virtual void Elif(SourceRange Range) {
+ virtual void Elif(SourceLocation Loc, SourceRange ConditionRange,
+ SourceLocation IfLoc) {
}
/// Ifdef -- This hook is called whenever an #ifdef is seen.
- /// \param Loc The location of the token being tested.
+ /// \param Loc the source location of the directive.
/// \param II Information on the token being tested.
- virtual void Ifdef(const Token &MacroNameTok) {
+ virtual void Ifdef(SourceLocation Loc, const Token &MacroNameTok) {
}
/// Ifndef -- This hook is called whenever an #ifndef is seen.
- /// \param Loc The location of the token being tested.
+ /// \param Loc the source location of the directive.
/// \param II Information on the token being tested.
- virtual void Ifndef(const Token &MacroNameTok) {
+ virtual void Ifndef(SourceLocation Loc, const Token &MacroNameTok) {
}
/// Else -- This hook is called whenever an #else is seen.
- virtual void Else() {
+ /// \param Loc the source location of the directive.
+ /// \param IfLoc the source location of the #if/#ifdef/#ifndef directive.
+ virtual void Else(SourceLocation Loc, SourceLocation IfLoc) {
}
/// Endif -- This hook is called whenever an #endif is seen.
- virtual void Endif() {
+ /// \param Loc the source location of the directive.
+ /// \param IfLoc the source location of the #if/#ifdef/#ifndef directive.
+ virtual void Endif(SourceLocation Loc, SourceLocation IfLoc) {
}
};
/// PPChainedCallbacks - Simple wrapper class for chaining callbacks.
class PPChainedCallbacks : public PPCallbacks {
+ virtual void anchor();
PPCallbacks *First, *Second;
public:
@@ -231,6 +257,12 @@ public:
Second->FileSkipped(ParentFile, FilenameTok, FileType);
}
+ virtual bool FileNotFound(StringRef FileName,
+ SmallVectorImpl<char> &RecoveryPath) {
+ return First->FileNotFound(FileName, RecoveryPath) ||
+ Second->FileNotFound(FileName, RecoveryPath);
+ }
+
virtual void InclusionDirective(SourceLocation HashLoc,
const Token &IncludeTok,
StringRef FileName,
@@ -311,39 +343,40 @@ public:
}
/// If -- This hook is called whenever an #if is seen.
- virtual void If(SourceRange Range) {
- First->If(Range);
- Second->If(Range);
+ virtual void If(SourceLocation Loc, SourceRange ConditionRange) {
+ First->If(Loc, ConditionRange);
+ Second->If(Loc, ConditionRange);
}
/// Elif -- This hook is called whenever an #if is seen.
- virtual void Elif(SourceRange Range) {
- First->Elif(Range);
- Second->Elif(Range);
+ virtual void Elif(SourceLocation Loc, SourceRange ConditionRange,
+ SourceLocation IfLoc) {
+ First->Elif(Loc, ConditionRange, IfLoc);
+ Second->Elif(Loc, ConditionRange, IfLoc);
}
/// Ifdef -- This hook is called whenever an #ifdef is seen.
- virtual void Ifdef(const Token &MacroNameTok) {
- First->Ifdef(MacroNameTok);
- Second->Ifdef(MacroNameTok);
+ virtual void Ifdef(SourceLocation Loc, const Token &MacroNameTok) {
+ First->Ifdef(Loc, MacroNameTok);
+ Second->Ifdef(Loc, MacroNameTok);
}
/// Ifndef -- This hook is called whenever an #ifndef is seen.
- virtual void Ifndef(const Token &MacroNameTok) {
- First->Ifndef(MacroNameTok);
- Second->Ifndef(MacroNameTok);
+ virtual void Ifndef(SourceLocation Loc, const Token &MacroNameTok) {
+ First->Ifndef(Loc, MacroNameTok);
+ Second->Ifndef(Loc, MacroNameTok);
}
/// Else -- This hook is called whenever an #else is seen.
- virtual void Else() {
- First->Else();
- Second->Else();
+ virtual void Else(SourceLocation Loc, SourceLocation IfLoc) {
+ First->Else(Loc, IfLoc);
+ Second->Else(Loc, IfLoc);
}
/// Endif -- This hook is called whenever an #endif is seen.
- virtual void Endif() {
- First->Endif();
- Second->Endif();
+ virtual void Endif(SourceLocation Loc, SourceLocation IfLoc) {
+ First->Endif(Loc, IfLoc);
+ Second->Endif(Loc, IfLoc);
}
};
diff --git a/include/clang/Lex/PreprocessingRecord.h b/include/clang/Lex/PreprocessingRecord.h
index 53da19e6c296..45e3a5d64730 100644
--- a/include/clang/Lex/PreprocessingRecord.h
+++ b/include/clang/Lex/PreprocessingRecord.h
@@ -17,8 +17,11 @@
#include "clang/Lex/PPCallbacks.h"
#include "clang/Basic/SourceLocation.h"
#include "clang/Basic/IdentifierTable.h"
+#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/Optional.h"
#include "llvm/Support/Allocator.h"
+#include "llvm/Support/Compiler.h"
#include <vector>
namespace clang {
@@ -85,7 +88,7 @@ namespace clang {
/// \brief Retrieve the source range that covers this entire preprocessed
/// entity.
- SourceRange getSourceRange() const { return Range; }
+ SourceRange getSourceRange() const LLVM_READONLY { return Range; }
/// \brief Returns true if there was a problem loading the preprocessed
/// entity.
@@ -269,6 +272,13 @@ namespace clang {
/// preprocessed entities that \arg Range encompasses.
virtual std::pair<unsigned, unsigned>
findPreprocessedEntitiesInRange(SourceRange Range) = 0;
+
+ /// \brief Optionally returns true or false if the preallocated preprocessed
+ /// entity with index \arg Index came from file \arg FID.
+ virtual llvm::Optional<bool> isPreprocessedEntityInFileID(unsigned Index,
+ FileID FID) {
+ return llvm::Optional<bool>();
+ }
};
/// \brief A record of the steps taken while preprocessing a source file,
@@ -276,10 +286,6 @@ namespace clang {
/// expanded, etc.
class PreprocessingRecord : public PPCallbacks {
SourceManager &SourceMgr;
-
- /// \brief Whether we should include nested macro expansions in
- /// the preprocessing record.
- bool IncludeNestedMacroExpansions;
/// \brief Allocator used to store preprocessing objects.
llvm::BumpPtrAllocator BumpAlloc;
@@ -295,6 +301,44 @@ namespace clang {
/// and are referenced by the iterator using negative indices.
std::vector<PreprocessedEntity *> LoadedPreprocessedEntities;
+ bool RecordCondDirectives;
+ unsigned CondDirectiveNextIdx;
+ SmallVector<unsigned, 6> CondDirectiveStack;
+
+ class CondDirectiveLoc {
+ SourceLocation Loc;
+ unsigned Idx;
+
+ public:
+ CondDirectiveLoc(SourceLocation Loc, unsigned Idx) : Loc(Loc), Idx(Idx) {}
+
+ SourceLocation getLoc() const { return Loc; }
+ unsigned getIdx() const { return Idx; }
+
+ class Comp {
+ SourceManager &SM;
+ public:
+ explicit Comp(SourceManager &SM) : SM(SM) {}
+ bool operator()(const CondDirectiveLoc &LHS,
+ const CondDirectiveLoc &RHS) {
+ return SM.isBeforeInTranslationUnit(LHS.getLoc(), RHS.getLoc());
+ }
+ bool operator()(const CondDirectiveLoc &LHS, SourceLocation RHS) {
+ return SM.isBeforeInTranslationUnit(LHS.getLoc(), RHS);
+ }
+ bool operator()(SourceLocation LHS, const CondDirectiveLoc &RHS) {
+ return SM.isBeforeInTranslationUnit(LHS, RHS.getLoc());
+ }
+ };
+ };
+
+ typedef std::vector<CondDirectiveLoc> CondDirectiveLocsTy;
+ /// \brief The locations of conditional directives in source order.
+ CondDirectiveLocsTy CondDirectiveLocs;
+
+ void addCondDirectiveLoc(CondDirectiveLoc DirLoc);
+ unsigned findCondDirectiveIdx(SourceLocation Loc) const;
+
/// \brief Global (loaded or local) ID for a preprocessed entity.
/// Negative values are used to indicate preprocessed entities
/// loaded from the external source while non-negative values are used to
@@ -345,7 +389,7 @@ namespace clang {
public:
/// \brief Construct a new preprocessing record.
- PreprocessingRecord(SourceManager &SM, bool IncludeNestedMacroExpansions);
+ PreprocessingRecord(SourceManager &SM, bool RecordConditionalDirectives);
/// \brief Allocate memory in the preprocessing record.
void *Allocate(unsigned Size, unsigned Align = 8) {
@@ -386,7 +430,7 @@ namespace clang {
iterator() : Self(0), Position(0) { }
- iterator(PreprocessingRecord *Self, int Position)
+ iterator(PreprocessingRecord *Self, PPEntityID Position)
: Self(Self), Position(Position) { }
value_type operator*() const {
@@ -471,6 +515,7 @@ namespace clang {
X.Position -= D;
return X;
}
+ friend class PreprocessingRecord;
};
friend class iterator;
@@ -496,11 +541,41 @@ namespace clang {
/// \brief Returns a pair of [Begin, End) iterators of preprocessed entities
/// that source range \arg R encompasses.
+ ///
+ /// \param R the range to look for preprocessed entities.
+ ///
std::pair<iterator, iterator> getPreprocessedEntitiesInRange(SourceRange R);
+ /// \brief Returns true if the preprocessed entity that \arg PPEI iterator
+ /// points to is coming from the file \arg FID.
+ ///
+ /// Can be used to avoid implicit deserializations of preallocated
+ /// preprocessed entities if we only care about entities of a specific file
+ /// and not from files #included in the range given at
+ /// \see getPreprocessedEntitiesInRange.
+ bool isEntityInFileID(iterator PPEI, FileID FID);
+
/// \brief Add a new preprocessed entity to this record.
- void addPreprocessedEntity(PreprocessedEntity *Entity);
-
+ PPEntityID addPreprocessedEntity(PreprocessedEntity *Entity);
+
+ /// \brief Returns true if this PreprocessingRecord is keeping track of
+ /// conditional directives locations.
+ bool isRecordingConditionalDirectives() const {
+ return RecordCondDirectives;
+ }
+
+ /// \brief Returns true if the given range intersects with a conditional
+ /// directive. if a #if/#endif block is fully contained within the range,
+ /// this function will return false.
+ bool rangeIntersectsConditionalDirective(SourceRange Range) const;
+
+ /// \brief Returns true if the given locations are in different regions,
+ /// separated by conditional directive blocks.
+ bool areInDifferentConditionalDirectiveRegion(SourceLocation LHS,
+ SourceLocation RHS) const {
+ return findCondDirectiveIdx(LHS) != findCondDirectiveIdx(RHS);
+ }
+
/// \brief Set the external source for preprocessed entities.
void SetExternalSource(ExternalPreprocessingRecordSource &Source);
@@ -513,6 +588,7 @@ namespace clang {
/// \c MacroInfo.
MacroDefinition *findMacroDefinition(const MacroInfo *MI);
+ private:
virtual void MacroExpands(const Token &Id, const MacroInfo* MI,
SourceRange Range);
virtual void MacroDefined(const Token &Id, const MacroInfo *MI);
@@ -525,6 +601,23 @@ namespace clang {
SourceLocation EndLoc,
StringRef SearchPath,
StringRef RelativePath);
+ virtual void If(SourceLocation Loc, SourceRange ConditionRange);
+ virtual void Elif(SourceLocation Loc, SourceRange ConditionRange,
+ SourceLocation IfLoc);
+ virtual void Ifdef(SourceLocation Loc, const Token &MacroNameTok);
+ virtual void Ifndef(SourceLocation Loc, const Token &MacroNameTok);
+ virtual void Else(SourceLocation Loc, SourceLocation IfLoc);
+ virtual void Endif(SourceLocation Loc, SourceLocation IfLoc);
+
+ /// \brief Cached result of the last \see getPreprocessedEntitiesInRange
+ /// query.
+ struct {
+ SourceRange Range;
+ std::pair<PPEntityID, PPEntityID> Result;
+ } CachedRangeQuery;
+
+ std::pair<PPEntityID, PPEntityID>
+ getPreprocessedEntitiesInRangeSlow(SourceRange R);
friend class ASTReader;
friend class ASTWriter;
diff --git a/include/clang/Lex/Preprocessor.h b/include/clang/Lex/Preprocessor.h
index 8b7743316f9c..055008fd44ce 100644
--- a/include/clang/Lex/Preprocessor.h
+++ b/include/clang/Lex/Preprocessor.h
@@ -33,6 +33,10 @@
#include "llvm/Support/Allocator.h"
#include <vector>
+namespace llvm {
+ template<unsigned InternalLen> class SmallString;
+}
+
namespace clang {
class SourceManager;
@@ -50,15 +54,15 @@ class CodeCompletionHandler;
class DirectoryLookup;
class PreprocessingRecord;
class ModuleLoader;
-
+
/// Preprocessor - This object engages in a tight little dance with the lexer to
/// efficiently preprocess tokens. Lexers know only about tokens within a
/// single source file, and don't know anything about preprocessor-level issues
/// like the #include stack, token expansion, etc.
///
-class Preprocessor : public llvm::RefCountedBase<Preprocessor> {
+class Preprocessor : public RefCountedBase<Preprocessor> {
DiagnosticsEngine *Diags;
- LangOptions &Features;
+ LangOptions &LangOpts;
const TargetInfo *Target;
FileManager &FileMgr;
SourceManager &SourceMgr;
@@ -69,10 +73,10 @@ class Preprocessor : public llvm::RefCountedBase<Preprocessor> {
/// \brief External source of macros.
ExternalPreprocessorSource *ExternalSource;
-
+
/// PTH - An optional PTHManager object used for getting tokens from
/// a token cache rather than lexing the original source file.
- llvm::OwningPtr<PTHManager> PTH;
+ OwningPtr<PTHManager> PTH;
/// BP - A BumpPtrAllocator object used to quickly allocate and release
/// objects internal to the Preprocessor.
@@ -107,8 +111,7 @@ class Preprocessor : public llvm::RefCountedBase<Preprocessor> {
bool KeepComments : 1;
bool KeepMacroComments : 1;
bool SuppressIncludeNotFoundError : 1;
- bool AutoModuleImport : 1;
-
+
// State that changes while the preprocessor runs:
bool InMacroArgs : 1; // True if parsing fn macro invocation args.
@@ -121,6 +124,9 @@ class Preprocessor : public llvm::RefCountedBase<Preprocessor> {
/// \brief Whether we have already loaded macros from the external source.
mutable bool ReadMacrosFromExternalSource : 1;
+ /// \brief True if we are pre-expanding macro arguments.
+ bool InMacroArgPreExpansion;
+
/// Identifiers - This is mapping/lookup information for all identifiers in
/// the program, including program keywords.
mutable IdentifierTable Identifiers;
@@ -145,9 +151,13 @@ class Preprocessor : public llvm::RefCountedBase<Preprocessor> {
/// with this preprocessor.
std::vector<CommentHandler *> CommentHandlers;
+ /// \brief True if we want to ignore EOF token and continue later on (thus
+ /// avoid tearing the Lexer and etc. down).
+ bool IncrementalProcessing;
+
/// \brief The code-completion handler.
CodeCompletionHandler *CodeComplete;
-
+
/// \brief The file that we're performing code-completion for, if any.
const FileEntry *CodeCompletionFile;
@@ -163,14 +173,22 @@ class Preprocessor : public llvm::RefCountedBase<Preprocessor> {
/// for preprocessing.
SourceLocation CodeCompletionFileLoc;
- /// \brief The source location of the __import_module__ keyword we just
+ /// \brief The source location of the 'import' contextual keyword we just
/// lexed, if any.
SourceLocation ModuleImportLoc;
+ /// \brief The module import path that we're currently processing.
+ llvm::SmallVector<std::pair<IdentifierInfo *, SourceLocation>, 2>
+ ModuleImportPath;
+
+ /// \brief Whether the module import expectes an identifier next. Otherwise,
+ /// it expects a '.' or ';'.
+ bool ModuleImportExpectsIdentifier;
+
/// \brief The source location of the currently-active
/// #pragma clang arc_cf_code_audited begin.
SourceLocation PragmaARCCFCodeAuditedLoc;
-
+
/// \brief True if we hit the code-completion point.
bool CodeCompletionReached;
@@ -179,22 +197,22 @@ class Preprocessor : public llvm::RefCountedBase<Preprocessor> {
/// with a flag that indicates whether skipping this number of bytes will
/// place the lexer at the start of a line.
std::pair<unsigned, bool> SkipMainFilePreamble;
-
+
/// CurLexer - This is the current top of the stack that we're lexing from if
/// not expanding a macro and we are lexing directly from source code.
/// Only one of CurLexer, CurPTHLexer, or CurTokenLexer will be non-null.
- llvm::OwningPtr<Lexer> CurLexer;
+ OwningPtr<Lexer> CurLexer;
/// CurPTHLexer - This is the current top of stack that we're lexing from if
/// not expanding from a macro and we are lexing from a PTH cache.
/// Only one of CurLexer, CurPTHLexer, or CurTokenLexer will be non-null.
- llvm::OwningPtr<PTHLexer> CurPTHLexer;
+ OwningPtr<PTHLexer> CurPTHLexer;
/// CurPPLexer - This is the current top of the stack what we're lexing from
/// if not expanding a macro. This is an alias for either CurLexer or
/// CurPTHLexer.
PreprocessorLexer *CurPPLexer;
-
+
/// CurLookup - The DirectoryLookup structure 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.
@@ -202,13 +220,13 @@ class Preprocessor : public llvm::RefCountedBase<Preprocessor> {
/// CurTokenLexer - This is the current macro we are expanding, if we are
/// expanding a macro. One of CurLexer and CurTokenLexer must be null.
- llvm::OwningPtr<TokenLexer> CurTokenLexer;
+ OwningPtr<TokenLexer> CurTokenLexer;
/// \brief The kind of lexer we're currently working with.
- enum CurLexerKind {
- CLK_Lexer,
- CLK_PTHLexer,
- CLK_TokenLexer,
+ enum CurLexerKind {
+ CLK_Lexer,
+ CLK_PTHLexer,
+ CLK_TokenLexer,
CLK_CachingLexer,
CLK_LexAfterModuleImport
} CurLexerKind;
@@ -224,10 +242,10 @@ class Preprocessor : public llvm::RefCountedBase<Preprocessor> {
TokenLexer *TheTokenLexer;
const DirectoryLookup *TheDirLookup;
- IncludeStackInfo(enum CurLexerKind K, Lexer *L, PTHLexer* P,
+ IncludeStackInfo(enum CurLexerKind K, Lexer *L, PTHLexer* P,
PreprocessorLexer* PPL,
TokenLexer* TL, const DirectoryLookup *D)
- : CurLexerKind(K), TheLexer(L), ThePTHLexer(P), ThePPLexer(PPL),
+ : CurLexerKind(K), TheLexer(L), ThePTHLexer(P), ThePPLexer(PPL),
TheTokenLexer(TL), TheDirLookup(D) {}
};
std::vector<IncludeStackInfo> IncludeMacroStack;
@@ -254,9 +272,9 @@ class Preprocessor : public llvm::RefCountedBase<Preprocessor> {
/// reused for quick allocation.
MacroArgs *MacroArgCache;
friend class MacroArgs;
-
- /// PragmaPushMacroInfo - For each IdentifierInfo used in a #pragma
- /// push_macro directive, we keep a MacroInfo stack used to restore
+
+ /// PragmaPushMacroInfo - For each IdentifierInfo used in a #pragma
+ /// push_macro directive, we keep a MacroInfo stack used to restore
/// previous macro value.
llvm::DenseMap<IdentifierInfo*, std::vector<MacroInfo*> > PragmaPushMacroInfo;
@@ -286,12 +304,12 @@ class Preprocessor : public llvm::RefCountedBase<Preprocessor> {
std::vector<std::pair<TokenLexer *, size_t> > MacroExpandingLexersStack;
/// \brief A record of the macro definitions and expansions that
- /// occurred during preprocessing.
+ /// occurred during preprocessing.
///
/// This is an optional side structure that can be enabled with
/// \c createPreprocessingRecord() prior to preprocessing.
PreprocessingRecord *Record;
-
+
private: // Cached tokens state.
typedef SmallVector<Token, 1> CachedTokensTy;
@@ -325,7 +343,7 @@ private: // Cached tokens state.
MacroInfoChain *MICache;
MacroInfo *getInfoForMacro(IdentifierInfo *II) const;
-
+
public:
Preprocessor(DiagnosticsEngine &diags, LangOptions &opts,
const TargetInfo *target,
@@ -333,7 +351,8 @@ public:
ModuleLoader &TheModuleLoader,
IdentifierInfoLookup *IILookup = 0,
bool OwnsHeaderSearch = false,
- bool DelayInitialization = false);
+ bool DelayInitialization = false,
+ bool IncrProcessing = false);
~Preprocessor();
@@ -342,11 +361,11 @@ public:
///
/// \param Target Information about the target.
void Initialize(const TargetInfo &Target);
-
+
DiagnosticsEngine &getDiagnostics() const { return *Diags; }
void setDiagnostics(DiagnosticsEngine &D) { Diags = &D; }
- const LangOptions &getLangOptions() const { return Features; }
+ const LangOptions &getLangOpts() const { return LangOpts; }
const TargetInfo &getTargetInfo() const { return *Target; }
FileManager &getFileManager() const { return FileMgr; }
SourceManager &getSourceManager() const { return SourceMgr; }
@@ -371,7 +390,7 @@ public:
/// \brief Retrieve the module loader associated with this preprocessor.
ModuleLoader &getModuleLoader() const { return TheModuleLoader; }
-
+
/// SetCommentRetentionState - Control whether or not the preprocessor retains
/// comments in output.
void SetCommentRetentionState(bool KeepComments, bool KeepMacroComments) {
@@ -389,11 +408,6 @@ public:
return SuppressIncludeNotFoundError;
}
- /// \brief Specify whether automatic module imports are enabled.
- void setAutoModuleImport(bool AutoModuleImport = true) {
- this->AutoModuleImport = AutoModuleImport;
- }
-
/// isCurrentLexer - Return true if we are lexing directly from the specified
/// lexer.
bool isCurrentLexer(const PreprocessorLexer *L) const {
@@ -425,13 +439,14 @@ public:
MacroInfo *getMacroInfo(IdentifierInfo *II) const {
if (!II->hasMacroDefinition())
return 0;
-
+
return getInfoForMacro(II);
}
/// setMacroInfo - Specify a macro for this identifier.
///
- void setMacroInfo(IdentifierInfo *II, MacroInfo *MI);
+ void setMacroInfo(IdentifierInfo *II, MacroInfo *MI,
+ bool LoadedFromAST = false);
/// macro_iterator/macro_begin/macro_end - This allows you to walk the current
/// state of the macro table. This visits every currently-defined macro.
@@ -484,29 +499,29 @@ public:
void setCodeCompletionHandler(CodeCompletionHandler &Handler) {
CodeComplete = &Handler;
}
-
+
/// \brief Retrieve the current code-completion handler.
CodeCompletionHandler *getCodeCompletionHandler() const {
return CodeComplete;
}
-
+
/// \brief Clear out the code completion handler.
void clearCodeCompletionHandler() {
CodeComplete = 0;
}
-
+
/// \brief Hook used by the lexer to invoke the "natural language" code
/// completion point.
void CodeCompleteNaturalLanguage();
-
+
/// \brief Retrieve the preprocessing record, or NULL if there is no
/// preprocessing record.
PreprocessingRecord *getPreprocessingRecord() const { return Record; }
-
- /// \brief Create a new preprocessing record, which will keep track of
+
+ /// \brief Create a new preprocessing record, which will keep track of
/// all macro expansions, macro definitions, etc.
- void createPreprocessingRecord(bool IncludeNestedMacroExpansions);
-
+ void createPreprocessingRecord(bool RecordConditionalDirectives);
+
/// EnterMainSourceFile - Enter the specified FileID as the main source file,
/// which implicitly adds the builtin defines etc.
void EnterMainSourceFile();
@@ -588,7 +603,7 @@ public:
}
void LexAfterModuleImport(Token &Result);
-
+
/// LexNonComment - Lex a token. If it's a comment, keep lexing until we get
/// something not a comment. This is useful in -E -C mode where comments
/// would foul up preprocessor directive handling.
@@ -681,6 +696,18 @@ public:
CachedTokens[CachedLexPos-1] = Tok;
}
+ /// \brief Recompute the current lexer kind based on the CurLexer/CurPTHLexer/
+ /// CurTokenLexer pointers.
+ void recomputeCurLexerKind();
+
+ /// \brief Returns true if incremental processing is enabled
+ bool isIncrementalProcessingEnabled() const { return IncrementalProcessing; }
+
+ /// \brief Enables the incremental processing
+ void enableIncrementalProcessing(bool value = true) {
+ IncrementalProcessing = value;
+ }
+
/// \brief Specify the point at which code-completion will be performed.
///
/// \param File the file in which code completion should occur. If
@@ -745,11 +772,11 @@ public:
///
/// \brief StartOfLine Whether skipping these bytes puts the lexer at the
/// start of a line.
- void setSkipMainFilePreamble(unsigned Bytes, bool StartOfLine) {
+ void setSkipMainFilePreamble(unsigned Bytes, bool StartOfLine) {
SkipMainFilePreamble.first = Bytes;
SkipMainFilePreamble.second = StartOfLine;
}
-
+
/// Diag - Forwarding function for diagnostics. This emits a diagnostic at
/// the specified Token's location, translating the token's start
/// position in the current buffer into a SourcePosition object for rendering.
@@ -771,7 +798,7 @@ public:
StringRef getSpelling(SourceLocation loc,
SmallVectorImpl<char> &buffer,
bool *invalid = 0) const {
- return Lexer::getSpelling(loc, buffer, SourceMgr, Features, invalid);
+ return Lexer::getSpelling(loc, buffer, SourceMgr, LangOpts, invalid);
}
/// getSpelling() - Return the 'spelling' of the Tok token. The spelling of a
@@ -782,7 +809,7 @@ public:
///
/// \param Invalid If non-null, will be set \c true if an error occurs.
std::string getSpelling(const Token &Tok, bool *Invalid = 0) const {
- return Lexer::getSpelling(Tok, SourceMgr, Features, Invalid);
+ return Lexer::getSpelling(Tok, SourceMgr, LangOpts, Invalid);
}
/// getSpelling - This method is used to get the spelling of a token into a
@@ -795,21 +822,21 @@ 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.
- unsigned getSpelling(const Token &Tok, const char *&Buffer,
+ unsigned getSpelling(const Token &Tok, const char *&Buffer,
bool *Invalid = 0) const {
- return Lexer::getSpelling(Tok, Buffer, SourceMgr, Features, Invalid);
+ return Lexer::getSpelling(Tok, Buffer, SourceMgr, LangOpts, Invalid);
}
/// getSpelling - This method is used to get the spelling of a token into a
/// SmallVector. Note that the returned StringRef may not point to the
/// supplied buffer if a copy can be avoided.
StringRef getSpelling(const Token &Tok,
- SmallVectorImpl<char> &Buffer,
- bool *Invalid = 0) const;
+ SmallVectorImpl<char> &Buffer,
+ bool *Invalid = 0) const;
/// getSpellingOfSingleCharacterNumericConstant - Tok is a numeric constant
/// with length 1, return the character.
- char getSpellingOfSingleCharacterNumericConstant(const Token &Tok,
+ char getSpellingOfSingleCharacterNumericConstant(const Token &Tok,
bool *Invalid = 0) const {
assert(Tok.is(tok::numeric_constant) &&
Tok.getLength() == 1 && "Called on unsupported token");
@@ -824,6 +851,17 @@ public:
return *SourceMgr.getCharacterData(Tok.getLocation(), Invalid);
}
+ /// \brief Retrieve the name of the immediate macro expansion.
+ ///
+ /// This routine starts from a source location, and finds the name of the macro
+ /// responsible for its immediate expansion. It looks through any intervening
+ /// macro argument expansions to compute this. It returns a StringRef which
+ /// refers to the SourceManager-owned buffer of the source where that macro
+ /// name is spelled. Thus, the result shouldn't out-live the SourceManager.
+ StringRef getImmediateMacroName(SourceLocation Loc) {
+ return Lexer::getImmediateMacroName(Loc, SourceMgr, getLangOpts());
+ }
+
/// CreateString - Plop the specified string into a scratch buffer and set the
/// specified token's location and length to it. If specified, the source
/// location provides a location of the expansion point of the token.
@@ -847,19 +885,28 @@ public:
/// location pointing just past the end of the token; an offset of 1 produces
/// a source location pointing to the last character in the token, etc.
SourceLocation getLocForEndOfToken(SourceLocation Loc, unsigned Offset = 0) {
- return Lexer::getLocForEndOfToken(Loc, Offset, SourceMgr, Features);
+ return Lexer::getLocForEndOfToken(Loc, Offset, SourceMgr, LangOpts);
}
/// \brief Returns true if the given MacroID location points at the first
/// token of the macro expansion.
- bool isAtStartOfMacroExpansion(SourceLocation loc) const {
- return Lexer::isAtStartOfMacroExpansion(loc, SourceMgr, Features);
+ ///
+ /// \param MacroBegin If non-null and function returns true, it is set to
+ /// begin location of the macro.
+ bool isAtStartOfMacroExpansion(SourceLocation loc,
+ SourceLocation *MacroBegin = 0) const {
+ return Lexer::isAtStartOfMacroExpansion(loc, SourceMgr, LangOpts,
+ MacroBegin);
}
/// \brief Returns true if the given MacroID location points at the last
/// token of the macro expansion.
- bool isAtEndOfMacroExpansion(SourceLocation loc) const {
- return Lexer::isAtEndOfMacroExpansion(loc, SourceMgr, Features);
+ ///
+ /// \param MacroBegin If non-null and function returns true, it is set to
+ /// end location of the macro.
+ bool isAtEndOfMacroExpansion(SourceLocation loc,
+ SourceLocation *MacroEnd = 0) const {
+ return Lexer::isAtEndOfMacroExpansion(loc, SourceMgr, LangOpts, MacroEnd);
}
/// DumpToken - Print the token to stderr, used for debugging.
@@ -872,7 +919,7 @@ public:
/// token, return a new location that specifies a character within the token.
SourceLocation AdvanceToTokenCharacter(SourceLocation TokStart,
unsigned Char) const {
- return Lexer::AdvanceToTokenCharacter(TokStart, Char, SourceMgr, Features);
+ return Lexer::AdvanceToTokenCharacter(TokStart, Char, SourceMgr, LangOpts);
}
/// IncrementPasteCounter - Increment the counters for the number of token
@@ -930,9 +977,18 @@ public:
private:
/// Identifiers used for SEH handling in Borland. These are only
/// allowed in particular circumstances
- IdentifierInfo *Ident__exception_code, *Ident___exception_code, *Ident_GetExceptionCode; // __except block
- IdentifierInfo *Ident__exception_info, *Ident___exception_info, *Ident_GetExceptionInfo; // __except filter expression
- IdentifierInfo *Ident__abnormal_termination, *Ident___abnormal_termination, *Ident_AbnormalTermination; // __finally
+ // __except block
+ IdentifierInfo *Ident__exception_code,
+ *Ident___exception_code,
+ *Ident_GetExceptionCode;
+ // __except filter expression
+ IdentifierInfo *Ident__exception_info,
+ *Ident___exception_info,
+ *Ident_GetExceptionInfo;
+ // __finally
+ IdentifierInfo *Ident__abnormal_termination,
+ *Ident___abnormal_termination,
+ *Ident_AbnormalTermination;
public:
void PoisonSEHIdentifiers(bool Poison = true); // Borland
@@ -976,6 +1032,9 @@ public:
unsigned getCounterValue() const { return CounterValue; }
void setCounterValue(unsigned V) { CounterValue = V; }
+ /// \brief Retrieves the module that we're currently building, if any.
+ Module *getCurrentModule();
+
/// AllocateMacroInfo - Allocate a new MacroInfo object with the provide
/// SourceLocation.
MacroInfo *AllocateMacroInfo(SourceLocation L);
@@ -999,7 +1058,8 @@ public:
const DirectoryLookup *&CurDir,
SmallVectorImpl<char> *SearchPath,
SmallVectorImpl<char> *RelativePath,
- StringRef *SuggestedModule);
+ Module **SuggestedModule,
+ bool SkipCache = false);
/// GetCurLookup - The DirectoryLookup structure used to find the current
/// FileEntry, if CurLexer is non-null and if applicable. This allows us to
@@ -1020,7 +1080,7 @@ public:
/// This code concatenates and consumes tokens up to the '>' token. It
/// returns false if the > was found, otherwise it returns true if it finds
/// and consumes the EOD marker.
- bool ConcatenateIncludeName(llvm::SmallString<128> &FilenameBuffer,
+ bool ConcatenateIncludeName(SmallString<128> &FilenameBuffer,
SourceLocation &End);
/// LexOnOffSwitch - Lex an on-off-switch (C99 6.10.6p2) and verify that it is
@@ -1063,9 +1123,10 @@ private:
/// ReadMacroDefinitionArgList - The ( starting an argument list of a macro
/// definition has just been read. Lex the rest of the arguments and the
- /// closing ), updating MI with what we learn. Return true if an error occurs
- /// parsing the arg list.
- bool ReadMacroDefinitionArgList(MacroInfo *MI);
+ /// closing ), updating MI with what we learn and saving in LastTok the
+ /// last token read.
+ /// Return true if an error occurs parsing the arg list.
+ bool ReadMacroDefinitionArgList(MacroInfo *MI, Token& LastTok);
/// SkipExcludedConditionalBlock - We just read a #if or related directive and
/// decided that the subsequent tokens are in the #if'd out portion of the
@@ -1163,7 +1224,7 @@ private:
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 == 0 && CurTokenLexer == 0 && CurPTHLexer == 0 &&
+ return CurPPLexer == 0 && CurTokenLexer == 0 && CurPTHLexer == 0 &&
!IncludeMacroStack.empty();
}
void EnterCachingLexMode();
@@ -1182,8 +1243,9 @@ private:
void HandleDigitDirective(Token &Tok);
void HandleUserDiagnosticDirective(Token &Tok, bool isWarning);
void HandleIdentSCCSDirective(Token &Tok);
- void HandleMacroExportDirective(Token &Tok);
-
+ void HandleMacroPublicDirective(Token &Tok);
+ void HandleMacroPrivateDirective(Token &Tok);
+
// File inclusion.
void HandleIncludeDirective(SourceLocation HashLoc,
Token &Tok,
@@ -1192,6 +1254,7 @@ private:
void HandleIncludeNextDirective(SourceLocation HashLoc, Token &Tok);
void HandleIncludeMacrosDirective(SourceLocation HashLoc, Token &Tok);
void HandleImportDirective(SourceLocation HashLoc, Token &Tok);
+ void HandleMicrosoftImportDirective(Token &Tok);
// Macro handling.
void HandleDefineDirective(Token &Tok);
@@ -1217,6 +1280,7 @@ public:
void HandlePragmaMessage(Token &MessageTok);
void HandlePragmaPushMacro(Token &Tok);
void HandlePragmaPopMacro(Token &Tok);
+ void HandlePragmaIncludeAlias(Token &Tok);
IdentifierInfo *ParsePragmaPushOrPopMacro(Token &Tok);
// Return true and store the first token only if any CommentHandler
diff --git a/include/clang/Lex/PreprocessorLexer.h b/include/clang/Lex/PreprocessorLexer.h
index e2e30bf87837..b551cd431018 100644
--- a/include/clang/Lex/PreprocessorLexer.h
+++ b/include/clang/Lex/PreprocessorLexer.h
@@ -24,6 +24,7 @@ class FileEntry;
class Preprocessor;
class PreprocessorLexer {
+ virtual void anchor();
protected:
Preprocessor *PP; // Preprocessor object controlling lexing.
diff --git a/include/clang/Lex/Token.h b/include/clang/Lex/Token.h
index e6dd1607e88b..a88f607298e8 100644
--- a/include/clang/Lex/Token.h
+++ b/include/clang/Lex/Token.h
@@ -75,7 +75,8 @@ public:
LeadingSpace = 0x02, // Whitespace exists before this token.
DisableExpand = 0x04, // This identifier may never be macro expanded.
NeedsCleaning = 0x08, // Contained an escaped newline or trigraph.
- LeadingEmptyMacro = 0x10 // Empty macro exists before this token.
+ LeadingEmptyMacro = 0x10, // Empty macro exists before this token.
+ HasUDSuffix = 0x20 // This string or character literal has a ud-suffix.
};
tok::TokenKind getKind() const { return (tok::TokenKind)Kind; }
@@ -263,6 +264,9 @@ public:
return (Flags & LeadingEmptyMacro) ? true : false;
}
+ /// \brief Return true if this token is a string or character literal which
+ /// has a ud-suffix.
+ bool hasUDSuffix() const { return (Flags & HasUDSuffix) ? true : false; }
};
/// PPConditionalInfo - Information about the conditional stack (#if directives)