summaryrefslogtreecommitdiffstats
path: root/include/clang/Lex
diff options
context:
space:
mode:
Diffstat (limited to 'include/clang/Lex')
-rw-r--r--include/clang/Lex/DirectoryLookup.h34
-rw-r--r--include/clang/Lex/ExternalPreprocessorSource.h4
-rw-r--r--include/clang/Lex/HeaderSearch.h30
-rw-r--r--include/clang/Lex/HeaderSearchOptions.h67
-rw-r--r--include/clang/Lex/Lexer.h50
-rw-r--r--include/clang/Lex/LiteralSupport.h8
-rw-r--r--include/clang/Lex/MacroInfo.h471
-rw-r--r--include/clang/Lex/ModuleLoader.h41
-rw-r--r--include/clang/Lex/ModuleMap.h55
-rw-r--r--include/clang/Lex/PPCallbacks.h66
-rw-r--r--include/clang/Lex/PPConditionalDirectiveRecord.h102
-rw-r--r--include/clang/Lex/PPMutationListener.h43
-rw-r--r--include/clang/Lex/PTHManager.h6
-rw-r--r--include/clang/Lex/PreprocessingRecord.h97
-rw-r--r--include/clang/Lex/Preprocessor.h184
-rw-r--r--include/clang/Lex/PreprocessorOptions.h52
-rw-r--r--include/clang/Lex/Token.h12
17 files changed, 863 insertions, 459 deletions
diff --git a/include/clang/Lex/DirectoryLookup.h b/include/clang/Lex/DirectoryLookup.h
index d773fc6..261dfab 100644
--- a/include/clang/Lex/DirectoryLookup.h
+++ b/include/clang/Lex/DirectoryLookup.h
@@ -50,34 +50,34 @@ private:
/// SrcMgr::CharacteristicKind.
unsigned DirCharacteristic : 2;
- /// UserSupplied - True if this is a user-supplied directory.
- ///
- bool UserSupplied : 1;
-
/// LookupType - This indicates whether this DirectoryLookup object is a
/// normal directory, a framework, or a headermap.
unsigned LookupType : 2;
/// \brief Whether this is a header map used when building a framework.
unsigned IsIndexHeaderMap : 1;
+
+ /// \brief Whether we've performed an exhaustive search for module maps
+ /// within the subdirectories of this directory.
+ unsigned SearchedAllModuleMaps : 1;
public:
/// DirectoryLookup ctor - Note that this ctor *does not take ownership* of
/// 'dir'.
DirectoryLookup(const DirectoryEntry *dir, SrcMgr::CharacteristicKind DT,
- bool isUser, bool isFramework)
- : DirCharacteristic(DT), UserSupplied(isUser),
+ bool isFramework)
+ : DirCharacteristic(DT),
LookupType(isFramework ? LT_Framework : LT_NormalDir),
- IsIndexHeaderMap(false) {
+ IsIndexHeaderMap(false), SearchedAllModuleMaps(false) {
u.Dir = dir;
}
/// DirectoryLookup ctor - Note that this ctor *does not take ownership* of
/// 'map'.
DirectoryLookup(const HeaderMap *map, SrcMgr::CharacteristicKind DT,
- bool isUser, bool isIndexHeaderMap)
- : DirCharacteristic(DT), UserSupplied(isUser), LookupType(LT_HeaderMap),
- IsIndexHeaderMap(isIndexHeaderMap) {
+ bool isIndexHeaderMap)
+ : DirCharacteristic(DT), LookupType(LT_HeaderMap),
+ IsIndexHeaderMap(isIndexHeaderMap), SearchedAllModuleMaps(false) {
u.Map = map;
}
@@ -113,16 +113,22 @@ public:
/// isHeaderMap - Return true if this is a header map, not a normal directory.
bool isHeaderMap() const { return getLookupType() == LT_HeaderMap; }
+ /// \brief Determine whether we have already searched this entire
+ /// directory for module maps.
+ bool haveSearchedAllModuleMaps() const { return SearchedAllModuleMaps; }
+
+ /// \brief Specify whether we have already searched all of the subdirectories
+ /// for module maps.
+ void setSearchedAllModuleMaps(bool SAMM) {
+ SearchedAllModuleMaps = SAMM;
+ }
+
/// DirCharacteristic - The type of directory this is, one of the DirType enum
/// values.
SrcMgr::CharacteristicKind getDirCharacteristic() const {
return (SrcMgr::CharacteristicKind)DirCharacteristic;
}
- /// isUserSupplied - True if this is a user-supplied directory.
- ///
- bool isUserSupplied() const { return UserSupplied; }
-
/// \brief Whether this header map is building a framework or not.
bool isIndexHeaderMap() const {
return isHeaderMap() && IsIndexHeaderMap;
diff --git a/include/clang/Lex/ExternalPreprocessorSource.h b/include/clang/Lex/ExternalPreprocessorSource.h
index d2e2412..d9a4de4 100644
--- a/include/clang/Lex/ExternalPreprocessorSource.h
+++ b/include/clang/Lex/ExternalPreprocessorSource.h
@@ -15,7 +15,9 @@
#define LLVM_CLANG_LEX_EXTERNAL_PREPROCESSOR_SOURCE_H
namespace clang {
-
+
+class IdentifierInfo;
+
/// \brief Abstract interface for external sources of preprocessor
/// information.
///
diff --git a/include/clang/Lex/HeaderSearch.h b/include/clang/Lex/HeaderSearch.h
index 4334db7..8a5a798 100644
--- a/include/clang/Lex/HeaderSearch.h
+++ b/include/clang/Lex/HeaderSearch.h
@@ -18,10 +18,10 @@
#include "clang/Lex/ModuleMap.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/IntrusiveRefCntPtr.h"
+#include "llvm/ADT/OwningPtr.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 {
@@ -50,6 +50,9 @@ struct HeaderFileInfo {
/// \brief Whether this header file info was supplied by an external source.
unsigned External : 1;
+
+ /// \brief Whether this header is part of a module.
+ unsigned isModuleHeader : 1;
/// \brief Whether this structure is considered to already have been
/// "resolved", meaning that it was loaded from the external source.
@@ -90,7 +93,8 @@ struct HeaderFileInfo {
HeaderFileInfo()
: isImport(false), isPragmaOnce(false), DirInfo(SrcMgr::C_User),
- External(false), Resolved(false), IndexHeaderMapHeader(false),
+ External(false), isModuleHeader(false), Resolved(false),
+ IndexHeaderMapHeader(false),
NumIncludes(0), ControllingMacroID(0), ControllingMacro(0) {}
/// \brief Retrieve the controlling macro for this header file, if
@@ -134,7 +138,7 @@ class HeaderSearch {
};
/// \brief Header-search options used to initialize this header search.
- llvm::IntrusiveRefCntPtr<HeaderSearchOptions> HSOpts;
+ IntrusiveRefCntPtr<HeaderSearchOptions> HSOpts;
FileManager &FileMgr;
/// \#include search path information. Requests for \#include "x" search the
@@ -189,7 +193,7 @@ class HeaderSearch {
std::vector<std::pair<const FileEntry*, const HeaderMap*> > HeaderMaps;
/// \brief The mapping between modules and headers.
- ModuleMap ModMap;
+ mutable ModuleMap ModMap;
/// \brief Describes whether a given directory has a module map in it.
llvm::DenseMap<const DirectoryEntry *, bool> DirectoryHasModuleMap;
@@ -217,7 +221,7 @@ class HeaderSearch {
friend class DirectoryLookup;
public:
- HeaderSearch(llvm::IntrusiveRefCntPtr<HeaderSearchOptions> HSOpts,
+ HeaderSearch(IntrusiveRefCntPtr<HeaderSearchOptions> HSOpts,
FileManager &FM, DiagnosticsEngine &Diags,
const LangOptions &LangOpts, const TargetInfo *Target);
~HeaderSearch();
@@ -363,7 +367,8 @@ public:
StringRef Filename,
const FileEntry *RelativeFileEnt,
SmallVectorImpl<char> *SearchPath,
- SmallVectorImpl<char> *RelativePath);
+ SmallVectorImpl<char> *RelativePath,
+ Module **SuggestedModule);
/// \brief Look up the specified framework name in our framework cache.
/// \returns The DirectoryEntry it is in if we know, null otherwise.
@@ -399,6 +404,9 @@ public:
getFileInfo(File).DirInfo = SrcMgr::C_System;
}
+ /// \brief Mark the specified file as part of a module.
+ void MarkFileModuleHeader(const FileEntry *File);
+
/// \brief Increment the count for the number of times the specified
/// FileEntry has been entered.
void IncrementIncludeCount(const FileEntry *File) {
@@ -468,7 +476,7 @@ public:
/// \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);
+ Module *findModuleForHeader(const FileEntry *File) const;
/// \brief Read the contents of the given module map file.
///
@@ -480,7 +488,7 @@ public:
/// \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);
+ void collectAllModules(SmallVectorImpl<Module *> &Modules);
private:
/// \brief Retrieve a module with the given name, which may be part of the
@@ -497,7 +505,11 @@ private:
Module *loadFrameworkModule(StringRef Name,
const DirectoryEntry *Dir,
bool IsSystem);
-
+
+ /// \brief Load all of the module maps within the immediate subdirectories
+ /// of the given search directory.
+ void loadSubdirectoryModuleMaps(DirectoryLookup &SearchDir);
+
public:
/// \brief Retrieve the module map.
ModuleMap &getModuleMap() { return ModMap; }
diff --git a/include/clang/Lex/HeaderSearchOptions.h b/include/clang/Lex/HeaderSearchOptions.h
index 468fefa..afce5ba 100644
--- a/include/clang/Lex/HeaderSearchOptions.h
+++ b/include/clang/Lex/HeaderSearchOptions.h
@@ -10,8 +10,11 @@
#ifndef LLVM_CLANG_LEX_HEADERSEARCHOPTIONS_H
#define LLVM_CLANG_LEX_HEADERSEARCHOPTIONS_H
+#include "clang/Basic/LLVM.h"
#include "llvm/ADT/IntrusiveRefCntPtr.h"
+#include "llvm/ADT/SetVector.h"
#include "llvm/ADT/StringRef.h"
+#include <string>
#include <vector>
namespace clang {
@@ -27,6 +30,8 @@ namespace frontend {
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.
@@ -37,12 +42,11 @@ namespace frontend {
/// HeaderSearchOptions - Helper class for storing options related to the
/// initialization of the HeaderSearch object.
-class HeaderSearchOptions : public llvm::RefCountedBase<HeaderSearchOptions> {
+class HeaderSearchOptions : public RefCountedBase<HeaderSearchOptions> {
public:
struct Entry {
std::string Path;
frontend::IncludeDirGroup Group;
- unsigned IsUserSupplied : 1;
unsigned IsFramework : 1;
/// IgnoreSysRoot - This is false if an absolute path should be treated
@@ -50,24 +54,10 @@ public:
/// path.
unsigned IgnoreSysRoot : 1;
- /// \brief True if this entry is an internal search path.
- ///
- /// This typically indicates that users didn't directly provide it, but
- /// instead it was provided by a compatibility layer for a particular
- /// system. This isn't redundant with IsUserSupplied (even though perhaps
- /// it should be) because that is false for user provided '-iwithprefix'
- /// header search entries.
- unsigned IsInternal : 1;
-
- /// \brief True if this entry's headers should be wrapped in extern "C".
- unsigned ImplicitExternC : 1;
-
- Entry(StringRef path, frontend::IncludeDirGroup group,
- bool isUserSupplied, bool isFramework, bool ignoreSysRoot,
- bool isInternal, bool implicitExternC)
- : Path(path), Group(group), IsUserSupplied(isUserSupplied),
- IsFramework(isFramework), IgnoreSysRoot(ignoreSysRoot),
- IsInternal(isInternal), ImplicitExternC(implicitExternC) {}
+ Entry(StringRef path, frontend::IncludeDirGroup group, bool isFramework,
+ bool ignoreSysRoot)
+ : Path(path), Group(group), IsFramework(isFramework),
+ IgnoreSysRoot(ignoreSysRoot) {}
};
struct SystemHeaderPrefix {
@@ -98,13 +88,35 @@ public:
/// \brief The directory used for the module cache.
std::string ModuleCachePath;
-
+
/// \brief Whether we should disable the use of the hash string within the
/// module cache.
///
/// Note: Only used for testing!
unsigned DisableModuleHash : 1;
-
+
+ /// \brief The interval (in seconds) between pruning operations.
+ ///
+ /// This operation is expensive, because it requires Clang to walk through
+ /// the directory structure of the module cache, stat()'ing and removing
+ /// files.
+ ///
+ /// The default value is large, e.g., the operation runs once a week.
+ unsigned ModuleCachePruneInterval;
+
+ /// \brief The time (in seconds) after which an unused module file will be
+ /// considered unused and will, therefore, be pruned.
+ ///
+ /// When the module cache is pruned, any module file that has not been
+ /// 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;
+
+ /// \brief The set of macro names that should be ignored for the purposes
+ /// of computing the module hash.
+ llvm::SetVector<std::string> ModulesIgnoreMacros;
+
/// Include the compiler builtin includes.
unsigned UseBuiltinIncludes : 1;
@@ -122,16 +134,17 @@ public:
public:
HeaderSearchOptions(StringRef _Sysroot = "/")
- : Sysroot(_Sysroot), DisableModuleHash(0), UseBuiltinIncludes(true),
+ : Sysroot(_Sysroot), DisableModuleHash(0),
+ ModuleCachePruneInterval(7*24*60*60),
+ ModuleCachePruneAfter(31*24*60*60),
+ UseBuiltinIncludes(true),
UseStandardSystemIncludes(true), UseStandardCXXIncludes(true),
UseLibcxx(false), Verbose(false) {}
/// AddPath - Add the \p Path path to the specified \p Group list.
void AddPath(StringRef Path, frontend::IncludeDirGroup Group,
- bool IsUserSupplied, bool IsFramework, bool IgnoreSysRoot,
- bool IsInternal = false, bool ImplicitExternC = false) {
- UserEntries.push_back(Entry(Path, Group, IsUserSupplied, IsFramework,
- IgnoreSysRoot, IsInternal, ImplicitExternC));
+ bool IsFramework, bool IgnoreSysRoot) {
+ UserEntries.push_back(Entry(Path, Group, IsFramework, IgnoreSysRoot));
}
/// AddSystemHeaderPrefix - Override whether \#include directives naming a
diff --git a/include/clang/Lex/Lexer.h b/include/clang/Lex/Lexer.h
index 407b644..cb4f57f 100644
--- a/include/clang/Lex/Lexer.h
+++ b/include/clang/Lex/Lexer.h
@@ -14,11 +14,11 @@
#ifndef LLVM_CLANG_LEXER_H
#define LLVM_CLANG_LEXER_H
-#include "clang/Lex/PreprocessorLexer.h"
#include "clang/Basic/LangOptions.h"
+#include "clang/Lex/PreprocessorLexer.h"
#include "llvm/ADT/SmallVector.h"
-#include <string>
#include <cassert>
+#include <string>
namespace clang {
class DiagnosticsEngine;
@@ -174,8 +174,8 @@ public:
/// SetKeepWhitespaceMode - This method lets clients enable or disable
/// whitespace retention mode.
void SetKeepWhitespaceMode(bool Val) {
- assert((!Val || LexingRawMode) &&
- "Can only enable whitespace retention in raw mode");
+ assert((!Val || LexingRawMode || LangOpts.TraditionalCPP) &&
+ "Can only retain whitespace in raw mode or -traditional-cpp");
ExtendedTokenMode = Val ? 2 : 0;
}
@@ -194,6 +194,14 @@ public:
ExtendedTokenMode = Mode ? 1 : 0;
}
+ /// Sets the extended token mode back to its initial value, according to the
+ /// language options and preprocessor. This controls whether the lexer
+ /// produces comment and whitespace tokens.
+ ///
+ /// This requires the lexer to have an associated preprocessor. A standalone
+ /// lexer has nothing to reset to.
+ void resetExtendedTokenMode();
+
const char *getBufferStart() const { return BufferStart; }
/// ReadToEndOfLine - Read the rest of the current preprocessor line as an
@@ -260,10 +268,10 @@ public:
/// location and does not jump to the expansion or spelling
/// location.
static StringRef getSpelling(SourceLocation loc,
- SmallVectorImpl<char> &buffer,
- const SourceManager &SourceMgr,
- const LangOptions &LangOpts,
- bool *invalid = 0);
+ SmallVectorImpl<char> &buffer,
+ const SourceManager &SourceMgr,
+ const LangOptions &LangOpts,
+ bool *invalid = 0);
/// 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.
@@ -273,6 +281,12 @@ public:
const SourceManager &SM,
const LangOptions &LangOpts);
+ /// \brief Relex the token at the specified location.
+ /// \returns true if there was a failure, false on success.
+ static bool getRawToken(SourceLocation Loc, Token &Result,
+ const SourceManager &SM,
+ const LangOptions &LangOpts);
+
/// \brief Given a location any where in a source buffer, find the location
/// that corresponds to the beginning of the token in which the original
/// source location lands.
@@ -431,6 +445,11 @@ private:
///
void LexTokenInternal(Token &Result);
+ /// Given that a token begins with the Unicode character \p C, figure out
+ /// what kind of token it is and dispatch to the appropriate lexing helper
+ /// function.
+ void LexUnicode(Token &Result, uint32_t C, const char *CurPtr);
+
/// FormTokenWithChars - When we lex a token, we have identified a span
/// starting at BufferPtr, going to TokEnd that forms the token. This method
/// takes that range and assigns it to the token as its location and size. In
@@ -573,6 +592,21 @@ private:
void cutOffLexing() { BufferPtr = BufferEnd; }
bool isHexaLiteral(const char *Start, const LangOptions &LangOpts);
+
+
+ /// Read a universal character name.
+ ///
+ /// \param CurPtr The position in the source buffer after the initial '\'.
+ /// If the UCN is syntactically well-formed (but not necessarily
+ /// 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
+ /// and handle token formation in the caller.
+ ///
+ /// \return The Unicode codepoint specified by the UCN, or 0 if the UCN is
+ /// invalid.
+ uint32_t tryReadUCN(const char *&CurPtr, const char *SlashLoc, Token *Tok);
};
diff --git a/include/clang/Lex/LiteralSupport.h b/include/clang/Lex/LiteralSupport.h
index 3b68d1b..b1430cc 100644
--- a/include/clang/Lex/LiteralSupport.h
+++ b/include/clang/Lex/LiteralSupport.h
@@ -15,13 +15,13 @@
#ifndef CLANG_LITERALSUPPORT_H
#define CLANG_LITERALSUPPORT_H
+#include "clang/Basic/CharInfo.h"
#include "clang/Basic/LLVM.h"
+#include "clang/Basic/TokenKinds.h"
#include "llvm/ADT/APFloat.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/DataTypes.h"
-#include "clang/Basic/TokenKinds.h"
-#include <cctype>
namespace clang {
@@ -101,7 +101,7 @@ private:
/// SkipHexDigits - Read and skip over any hex digits, up to End.
/// Return a pointer to the first non-hex digit or End.
const char *SkipHexDigits(const char *ptr) {
- while (ptr != ThisTokEnd && isxdigit(*ptr))
+ while (ptr != ThisTokEnd && isHexDigit(*ptr))
ptr++;
return ptr;
}
@@ -117,7 +117,7 @@ private:
/// SkipDigits - Read and skip over any digits, up to End.
/// Return a pointer to the first non-hex digit or End.
const char *SkipDigits(const char *ptr) {
- while (ptr != ThisTokEnd && isdigit(*ptr))
+ while (ptr != ThisTokEnd && isDigit(*ptr))
ptr++;
return ptr;
}
diff --git a/include/clang/Lex/MacroInfo.h b/include/clang/Lex/MacroInfo.h
index aba77d5..64323b7 100644
--- a/include/clang/Lex/MacroInfo.h
+++ b/include/clang/Lex/MacroInfo.h
@@ -6,9 +6,10 @@
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
-//
-// This file defines the MacroInfo interface.
-//
+///
+/// \file
+/// \brief Defines the clang::MacroInfo and clang::MacroDirective classes.
+///
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_MACROINFO_H
@@ -22,34 +23,28 @@
namespace clang {
class Preprocessor;
-/// MacroInfo - Each identifier that is \#define'd has an instance of this class
-/// associated with it, used to implement macro expansion.
+/// \brief Encapsulates the data about a macro definition (e.g. its tokens).
+///
+/// There's an instance of this class for every #define.
class MacroInfo {
//===--------------------------------------------------------------------===//
// State set when the macro is defined.
- /// Location - This is the place the macro is defined.
+ /// \brief The location the macro is defined.
SourceLocation Location;
- /// EndLocation - The location of the last token in the macro.
+ /// \brief The location of the last token in the macro.
SourceLocation EndLocation;
- /// \brief The location where the macro was #undef'd, or an invalid location
- /// for macros that haven't been undefined.
- SourceLocation UndefLocation;
- /// \brief Previous definition, the identifier of this macro was defined to,
- /// or NULL.
- MacroInfo *PreviousDefinition;
- /// Arguments - The list of arguments for a function-like macro. This can be
- /// empty, for, e.g. "#define X()". In a C99-style variadic macro, this
+ /// \brief The list of arguments for a function-like macro.
+ ///
+ /// ArgumentList points to the first of NumArguments pointers.
+ ///
+ /// 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 **ArgumentList;
- unsigned NumArguments;
- /// \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 given any visibility.
- SourceLocation VisibilityLocation;
+ /// \see ArgumentList
+ unsigned NumArguments;
/// \brief This is the list of tokens that the macro is defined to.
SmallVector<Token, 8> ReplacementTokens;
@@ -58,119 +53,88 @@ class MacroInfo {
mutable unsigned DefinitionLength;
mutable bool IsDefinitionLengthCached : 1;
- /// \brief True if this macro is a function-like macro, false if it
- /// is an object-like macro.
+ /// \brief True if this macro is function-like, false if it is object-like.
bool IsFunctionLike : 1;
- /// IsC99Varargs - True if this macro is of the form "#define X(...)" or
- /// "#define X(Y,Z,...)". The __VA_ARGS__ token should be replaced with the
- /// contents of "..." in an invocation.
+ /// \brief True if this macro is of the form "#define X(...)" or
+ /// "#define X(Y,Z,...)".
+ ///
+ /// The __VA_ARGS__ token should be replaced with the contents of "..." in an
+ /// invocation.
bool IsC99Varargs : 1;
- /// IsGNUVarargs - True if this macro is of the form "#define X(a...)". The
- /// "a" identifier in the replacement list will be replaced with all arguments
+ /// \brief True if this macro is of the form "#define X(a...)".
+ ///
+ /// The "a" identifier in the replacement list will be replaced with all arguments
/// of the macro starting with the specified one.
bool IsGNUVarargs : 1;
- /// IsBuiltinMacro - True if this is a builtin macro, such as __LINE__, and if
- /// it has not yet been redefined or undefined.
+ /// \brief True if this macro requires processing before expansion.
+ ///
+ /// This is the case for builtin macros such as __LINE__, so long as they have
+ /// not been redefined, but not for regular predefined macros from the "<built-in>"
+ /// memory buffer (see Preprocessing::getPredefinesFileID).
bool IsBuiltinMacro : 1;
- /// \brief True if this macro was loaded from an AST file.
- bool IsFromAST : 1;
-
- /// \brief Whether this macro changed after it was loaded from an AST file.
- bool ChangedAfterLoad : 1;
+ /// \brief Whether this macro contains the sequence ", ## __VA_ARGS__"
+ bool HasCommaPasting : 1;
private:
//===--------------------------------------------------------------------===//
// State that changes as the macro is used.
- /// IsDisabled - True if we have started an expansion of this macro already.
+ /// \brief True if we have started an expansion of this macro already.
+ ///
/// This disables recursive expansion, which would be quite bad for things
/// like \#define A A.
bool IsDisabled : 1;
- /// IsUsed - True if this macro is either defined in the main file and has
- /// been used, or if it is not defined in the main file. This is used to
- /// emit -Wunused-macros diagnostics.
+ /// \brief True if this macro is either defined in the main file and has
+ /// been used, or if it is not defined in the main file.
+ ///
+ /// This is used to emit -Wunused-macros diagnostics.
bool IsUsed : 1;
- /// AllowRedefinitionsWithoutWarning - True if this macro can be redefined
- /// without emitting a warning.
+ /// \brief True if this macro can be redefined without emitting a warning.
bool IsAllowRedefinitionsWithoutWarning : 1;
/// \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;
- /// \brief Whether the macro definition is currently "hidden".
- /// Note that this is transient state that is never serialized to the AST
- /// file.
- bool IsHidden : 1;
+ /// \brief Whether this macro info was loaded from an AST file.
+ unsigned FromASTFile : 1;
- /// \brief Whether the definition of this macro is ambiguous, due to
- /// multiple definitions coming in from multiple modules.
- bool IsAmbiguous : 1;
-
- ~MacroInfo() {
+ ~MacroInfo() {
assert(ArgumentList == 0 && "Didn't call destroy before dtor!");
}
public:
MacroInfo(SourceLocation DefLoc);
- MacroInfo(const MacroInfo &MI, llvm::BumpPtrAllocator &PPAllocator);
- /// FreeArgumentList - Free the argument list of the macro, restoring it to a
- /// state where it can be reused for other devious purposes.
+ /// \brief Free the argument list of the macro.
+ ///
+ /// This restores this MacroInfo to a state where it can be reused for other
+ /// devious purposes.
void FreeArgumentList() {
ArgumentList = 0;
NumArguments = 0;
}
- /// Destroy - destroy this MacroInfo object.
+ /// \brief Destroy this MacroInfo object.
void Destroy() {
FreeArgumentList();
this->~MacroInfo();
}
- /// getDefinitionLoc - Return the location that the macro was defined at.
- ///
+ /// \brief Return the location that the macro was defined at.
SourceLocation getDefinitionLoc() const { return Location; }
- /// setDefinitionEndLoc - Set the location of the last token in the macro.
- ///
+ /// \brief Set the location of the last token in the macro.
void setDefinitionEndLoc(SourceLocation EndLoc) { EndLocation = EndLoc; }
- /// getDefinitionEndLoc - Return the location of the last token in the macro.
- ///
+ /// \brief Return the location of the last token in the macro.
SourceLocation getDefinitionEndLoc() const { return EndLocation; }
- /// \brief Set the location where macro was undefined. Can only be set once.
- void setUndefLoc(SourceLocation UndefLoc) {
- assert(UndefLocation.isInvalid() && "UndefLocation is already set!");
- assert(UndefLoc.isValid() && "Invalid UndefLoc!");
- UndefLocation = UndefLoc;
- }
-
- /// \brief Get the location where macro was undefined.
- SourceLocation getUndefLoc() const { return UndefLocation; }
-
- /// \brief Set previous definition of the macro with the same name.
- void setPreviousDefinition(MacroInfo *PreviousDef) {
- PreviousDefinition = PreviousDef;
- }
-
- /// \brief Get previous definition of the macro with the same name.
- MacroInfo *getPreviousDefinition() { return PreviousDefinition; }
-
- /// \brief Find macro definition active in the specified source location. If
- /// this macro was not defined there, return NULL.
- const MacroInfo *findDefinitionAtLoc(SourceLocation L,
- SourceManager &SM) const;
-
/// \brief Get length in characters of the macro definition.
unsigned getDefinitionLength(SourceManager &SM) const {
if (IsDefinitionLengthCached)
@@ -178,25 +142,27 @@ public:
return getDefinitionLengthSlow(SM);
}
- /// isIdenticalTo - Return true if the specified macro definition is equal to
- /// this macro in spelling, arguments, and whitespace. This is used to emit
- /// duplicate definition warnings. This implements the rules in C99 6.10.3.
- bool isIdenticalTo(const MacroInfo &Other, Preprocessor &PP) const;
-
- /// setIsBuiltinMacro - Set or clear the isBuiltinMacro flag.
+ /// \brief Return true if the specified macro definition is equal to
+ /// this macro in spelling, arguments, and whitespace.
///
+ /// \param Syntactically if true, the macro definitions can be identical even
+ /// if they use different identifiers for the function macro parameters.
+ /// Otherwise the comparison is lexical and this implements the rules in
+ /// C99 6.10.3.
+ bool isIdenticalTo(const MacroInfo &Other, Preprocessor &PP,
+ bool Syntactically) const;
+
+ /// \brief Set or clear the isBuiltinMacro flag.
void setIsBuiltinMacro(bool Val = true) {
IsBuiltinMacro = Val;
}
- /// setIsUsed - Set the value of the IsUsed flag.
- ///
+ /// \brief Set the value of the IsUsed flag.
void setIsUsed(bool Val) {
IsUsed = Val;
}
- /// setIsAllowRedefinitionsWithoutWarning - Set the value of the
- /// IsAllowRedefinitionsWithoutWarning flag.
+ /// \brief Set the value of the IsAllowRedefinitionsWithoutWarning flag.
void setIsAllowRedefinitionsWithoutWarning(bool Val) {
IsAllowRedefinitionsWithoutWarning = Val;
}
@@ -206,8 +172,8 @@ public:
IsWarnIfUnused = val;
}
- /// setArgumentList - Set the specified list of identifiers as the argument
- /// list for this macro.
+ /// \brief Set the specified list of identifiers as the argument list for
+ /// this macro.
void setArgumentList(IdentifierInfo* const *List, unsigned NumArgs,
llvm::BumpPtrAllocator &PPAllocator) {
assert(ArgumentList == 0 && NumArguments == 0 &&
@@ -228,7 +194,7 @@ public:
arg_iterator arg_end() const { return ArgumentList+NumArguments; }
unsigned getNumArgs() const { return NumArguments; }
- /// getArgumentNum - Return the argument number of the specified identifier,
+ /// \brief Return the argument number of the specified identifier,
/// or -1 if the identifier is not a formal argument identifier.
int getArgumentNum(IdentifierInfo *Arg) const {
for (arg_iterator I = arg_begin(), E = arg_end(); I != E; ++I)
@@ -249,30 +215,22 @@ public:
bool isGNUVarargs() const { return IsGNUVarargs; }
bool isVariadic() const { return IsC99Varargs | IsGNUVarargs; }
- /// isBuiltinMacro - Return true if this macro is a builtin macro, such as
- /// __LINE__, which requires processing before expansion.
+ /// \brief Return true if this macro requires processing before expansion.
+ ///
+ /// This is true only for builtin macro, such as \__LINE__, whose values
+ /// are not given by fixed textual expansions. Regular predefined macros
+ /// from the "<built-in>" buffer are not reported as builtins by this
+ /// function.
bool isBuiltinMacro() const { return IsBuiltinMacro; }
- /// isFromAST - Return true if this macro was loaded from an AST file.
- bool isFromAST() const { return IsFromAST; }
-
- /// setIsFromAST - Set whether this macro was loaded from an AST file.
- void setIsFromAST(bool FromAST = true) { IsFromAST = FromAST; }
+ bool hasCommaPasting() const { return HasCommaPasting; }
+ void setHasCommaPasting() { HasCommaPasting = true; }
- /// \brief Determine whether this macro has changed since it was loaded from
- /// an AST file.
- bool hasChangedAfterLoad() const { return ChangedAfterLoad; }
-
- /// \brief Note whether this macro has changed after it was loaded from an
- /// AST file.
- void setChangedAfterLoad(bool CAL = true) { ChangedAfterLoad = CAL; }
-
- /// isUsed - Return false if this macro is defined in the main file and has
+ /// \brief Return false if this macro is defined in the main file and has
/// not yet been used.
bool isUsed() const { return IsUsed; }
- /// isAllowRedefinitionsWithoutWarning - Return true if this macro can be
- /// redefined without warning.
+ /// \brief Return true if this macro can be redefined without warning.
bool isAllowRedefinitionsWithoutWarning() const {
return IsAllowRedefinitionsWithoutWarning;
}
@@ -282,7 +240,7 @@ public:
return IsWarnIfUnused;
}
- /// getNumTokens - Return the number of tokens that this macro expands to.
+ /// \brief Return the number of tokens that this macro expands to.
///
unsigned getNumTokens() const {
return ReplacementTokens.size();
@@ -298,16 +256,16 @@ public:
tokens_iterator tokens_end() const { return ReplacementTokens.end(); }
bool tokens_empty() const { return ReplacementTokens.empty(); }
- /// AddTokenToBody - Add the specified token to the replacement text for the
- /// macro.
+ /// \brief Add the specified token to the replacement text for the macro.
void AddTokenToBody(const Token &Tok) {
assert(!IsDefinitionLengthCached &&
"Changing replacement tokens after definition length got calculated");
ReplacementTokens.push_back(Tok);
}
- /// isEnabled - Return true if this macro is enabled: in other words, that we
- /// are not currently in an expansion of this macro.
+ /// \brief Return true if this macro is enabled.
+ ///
+ /// In other words, that we are not currently in an expansion of this macro.
bool isEnabled() const { return !IsDisabled; }
void EnableMacro() {
@@ -320,41 +278,272 @@ public:
IsDisabled = true;
}
- /// \brief Set the export location for this macro.
- void setVisibility(bool Public, SourceLocation Loc) {
- VisibilityLocation = Loc;
- IsPublic = Public;
+ /// \brief Determine whether this macro info came from an AST file (such as
+ /// a precompiled header or module) rather than having been parsed.
+ bool isFromASTFile() const { return FromASTFile; }
+
+ /// \brief Retrieve the global ID of the module that owns this particular
+ /// macro info.
+ unsigned getOwningModuleID() const {
+ if (isFromASTFile())
+ return *(const unsigned*)(this+1);
+
+ return 0;
}
- /// \brief Determine whether this macro is part of the public API of its
- /// module.
- bool isPublic() const { return IsPublic; }
-
- /// \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;
+
+ void setOwningModuleID(unsigned ID) {
+ assert(isFromASTFile());
+ *(unsigned*)(this+1) = ID;
+ }
+
+ friend class Preprocessor;
+};
+
+class DefMacroDirective;
+
+/// \brief Encapsulates changes to the "macros namespace" (the location where
+/// the macro name became active, the location where it was undefined, etc.).
+///
+/// MacroDirectives, associated with an identifier, are used to model the macro
+/// history. Usually a macro definition (MacroInfo) is where a macro name
+/// becomes active (MacroDirective) but modules can have their own macro
+/// history, separate from the local (current translation unit) macro history.
+///
+/// For example, if "@import A;" imports macro FOO, there will be a new local
+/// MacroDirective created to indicate that "FOO" became active at the import
+/// location. Module "A" itself will contain another MacroDirective in its macro
+/// history (at the point of the definition of FOO) and both MacroDirectives
+/// will point to the same MacroInfo object.
+///
+class MacroDirective {
+public:
+ enum Kind {
+ MD_Define,
+ MD_Undefine,
+ MD_Visibility
+ };
+
+protected:
+ /// \brief Previous macro directive for the same identifier, or NULL.
+ MacroDirective *Previous;
+
+ SourceLocation Loc;
+
+ /// \brief MacroDirective kind.
+ unsigned MDKind : 2;
+
+ /// \brief True if the macro directive was loaded from a PCH file.
+ bool IsFromPCH : 1;
- /// \brief Determine whether this macro is currently defined (and has not
- /// been #undef'd) or has been hidden.
- bool isDefined() const { return UndefLocation.isInvalid() && !IsHidden; }
+ /// \brief Whether the macro directive is currently "hidden".
+ ///
+ /// Note that this is transient state that is never serialized to the AST
+ /// file.
+ bool IsHidden : 1;
+
+ // Used by DefMacroDirective -----------------------------------------------//
- /// \brief Determine whether this macro definition is hidden.
+ /// \brief True if this macro was imported from a module.
+ bool IsImported : 1;
+
+ /// \brief Whether the definition of this macro is ambiguous, due to
+ /// multiple definitions coming in from multiple modules.
+ bool IsAmbiguous : 1;
+
+ // Used by VisibilityMacroDirective ----------------------------------------//
+
+ /// \brief Whether the macro has public visibility (when described in a
+ /// module).
+ bool IsPublic : 1;
+
+ MacroDirective(Kind K, SourceLocation Loc)
+ : Previous(0), Loc(Loc), MDKind(K), IsFromPCH(false), IsHidden(false),
+ IsImported(false), IsAmbiguous(false),
+ IsPublic(true) {
+ }
+
+public:
+ Kind getKind() const { return Kind(MDKind); }
+
+ SourceLocation getLocation() const { return Loc; }
+
+ /// \brief Set previous definition of the macro with the same name.
+ void setPrevious(MacroDirective *Prev) {
+ Previous = Prev;
+ }
+
+ /// \brief Get previous definition of the macro with the same name.
+ const MacroDirective *getPrevious() const { return Previous; }
+
+ /// \brief Get previous definition of the macro with the same name.
+ MacroDirective *getPrevious() { return Previous; }
+
+ /// \brief Return true if the macro directive was loaded from a PCH file.
+ bool isFromPCH() const { return IsFromPCH; }
+
+ void setIsFromPCH() { IsFromPCH = true; }
+
+ /// \brief Determine whether this macro directive is hidden.
bool isHidden() const { return IsHidden; }
- /// \brief Set whether this macro definition is hidden.
+ /// \brief Set whether this macro directive is hidden.
void setHidden(bool Val) { IsHidden = Val; }
+ class DefInfo {
+ DefMacroDirective *DefDirective;
+ SourceLocation UndefLoc;
+ bool IsPublic;
+
+ public:
+ DefInfo() : DefDirective(0) { }
+
+ DefInfo(DefMacroDirective *DefDirective, SourceLocation UndefLoc,
+ bool isPublic)
+ : DefDirective(DefDirective), UndefLoc(UndefLoc), IsPublic(isPublic) { }
+
+ const DefMacroDirective *getDirective() const { return DefDirective; }
+ DefMacroDirective *getDirective() { return DefDirective; }
+
+ inline SourceLocation getLocation() const;
+ inline MacroInfo *getMacroInfo();
+ const MacroInfo *getMacroInfo() const {
+ return const_cast<DefInfo*>(this)->getMacroInfo();
+ }
+
+ SourceLocation getUndefLocation() const { return UndefLoc; }
+ bool isUndefined() const { return UndefLoc.isValid(); }
+
+ bool isPublic() const { return IsPublic; }
+
+ bool isValid() const { return DefDirective != 0; }
+ bool isInvalid() const { return !isValid(); }
+
+ operator bool() const { return isValid(); }
+
+ inline DefInfo getPreviousDefinition(bool AllowHidden = false);
+ const DefInfo getPreviousDefinition(bool AllowHidden = false) const {
+ return const_cast<DefInfo*>(this)->getPreviousDefinition(AllowHidden);
+ }
+ };
+
+ /// \brief Traverses the macro directives history and returns the next
+ /// macro definition directive along with info about its undefined location
+ /// (if there is one) and if it is public or private.
+ DefInfo getDefinition(bool AllowHidden = false);
+ const DefInfo getDefinition(bool AllowHidden = false) const {
+ return const_cast<MacroDirective*>(this)->getDefinition(AllowHidden);
+ }
+
+ bool isDefined(bool AllowHidden = false) const {
+ if (const DefInfo Def = getDefinition(AllowHidden))
+ return !Def.isUndefined();
+ return false;
+ }
+
+ const MacroInfo *getMacroInfo(bool AllowHidden = false) const {
+ return getDefinition(AllowHidden).getMacroInfo();
+ }
+ MacroInfo *getMacroInfo(bool AllowHidden = false) {
+ return getDefinition(AllowHidden).getMacroInfo();
+ }
+
+ /// \brief Find macro definition active in the specified source location. If
+ /// this macro was not defined there, return NULL.
+ const DefInfo findDirectiveAtLoc(SourceLocation L, SourceManager &SM) const;
+
+ static bool classof(const MacroDirective *) { return true; }
+};
+
+/// \brief A directive for a defined macro or a macro imported from a module.
+class DefMacroDirective : public MacroDirective {
+ MacroInfo *Info;
+
+public:
+ explicit DefMacroDirective(MacroInfo *MI)
+ : MacroDirective(MD_Define, MI->getDefinitionLoc()), Info(MI) {
+ assert(MI && "MacroInfo is null");
+ }
+
+ DefMacroDirective(MacroInfo *MI, SourceLocation Loc, bool isImported)
+ : MacroDirective(MD_Define, Loc), Info(MI) {
+ assert(MI && "MacroInfo is null");
+ IsImported = isImported;
+ }
+
+ /// \brief The data for the macro definition.
+ const MacroInfo *getInfo() const { return Info; }
+ MacroInfo *getInfo() { return Info; }
+
+ /// \brief True if this macro was imported from a module.
+ bool isImported() const { return IsImported; }
+
/// \brief Determine whether this macro definition is ambiguous with
/// other macro definitions.
bool isAmbiguous() const { return IsAmbiguous; }
/// \brief Set whether this macro definition is ambiguous.
void setAmbiguous(bool Val) { IsAmbiguous = Val; }
-
-private:
- unsigned getDefinitionLengthSlow(SourceManager &SM) const;
+
+ static bool classof(const MacroDirective *MD) {
+ return MD->getKind() == MD_Define;
+ }
+ static bool classof(const DefMacroDirective *) { return true; }
+};
+
+/// \brief A directive for an undefined macro.
+class UndefMacroDirective : public MacroDirective {
+public:
+ explicit UndefMacroDirective(SourceLocation UndefLoc)
+ : MacroDirective(MD_Undefine, UndefLoc) {
+ assert(UndefLoc.isValid() && "Invalid UndefLoc!");
+ }
+
+ static bool classof(const MacroDirective *MD) {
+ return MD->getKind() == MD_Undefine;
+ }
+ static bool classof(const UndefMacroDirective *) { return true; }
+};
+
+/// \brief A directive for setting the module visibility of a macro.
+class VisibilityMacroDirective : public MacroDirective {
+public:
+ explicit VisibilityMacroDirective(SourceLocation Loc, bool Public)
+ : MacroDirective(MD_Visibility, Loc) {
+ IsPublic = Public;
+ }
+
+ /// \brief Determine whether this macro is part of the public API of its
+ /// module.
+ bool isPublic() const { return IsPublic; }
+
+ 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 DefDirective->getLocation();
+}
+
+inline MacroInfo *MacroDirective::DefInfo::getMacroInfo() {
+ if (isInvalid())
+ return 0;
+ return DefDirective->getInfo();
+}
+
+inline MacroDirective::DefInfo
+MacroDirective::DefInfo::getPreviousDefinition(bool AllowHidden) {
+ if (isInvalid() || DefDirective->getPrevious() == 0)
+ return DefInfo();
+ return DefDirective->getPrevious()->getDefinition(AllowHidden);
+}
+
} // end namespace clang
#endif
diff --git a/include/clang/Lex/ModuleLoader.h b/include/clang/Lex/ModuleLoader.h
index 36d03c0..3acf915 100644
--- a/include/clang/Lex/ModuleLoader.h
+++ b/include/clang/Lex/ModuleLoader.h
@@ -17,16 +17,36 @@
#include "clang/Basic/Module.h"
#include "clang/Basic/SourceLocation.h"
#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/PointerIntPair.h"
namespace clang {
class IdentifierInfo;
-
+class Module;
+
/// \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;
-
+typedef ArrayRef<std::pair<IdentifierInfo *, SourceLocation> > ModuleIdPath;
+
+/// \brief Describes the result of attempting to load a module.
+class ModuleLoadResult {
+ llvm::PointerIntPair<Module *, 1, bool> Storage;
+
+public:
+ ModuleLoadResult() : Storage() { }
+
+ ModuleLoadResult(Module *module, bool missingExpected)
+ : Storage(module, missingExpected) { }
+
+ operator Module *() const { return Storage.getPointer(); }
+
+ /// \brief Determines whether the module, which failed to load, was
+ /// actually a submodule that we expected to see (based on implying the
+ /// submodule from header structure), but didn't materialize in the actual
+ /// module.
+ bool isMissingExpected() const { return Storage.getInt(); }
+};
+
/// \brief Abstract interface for a module loader.
///
/// This abstract interface describes a module loader, which is responsible
@@ -55,9 +75,16 @@ public:
///
/// \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;
+ virtual ModuleLoadResult loadModule(SourceLocation ImportLoc,
+ ModuleIdPath Path,
+ Module::NameVisibilityKind Visibility,
+ bool IsInclusionDirective) = 0;
+
+ /// \brief Make the given module visible.
+ virtual void makeModuleVisible(Module *Mod,
+ Module::NameVisibilityKind Visibility,
+ SourceLocation ImportLoc,
+ bool Complain) = 0;
};
}
diff --git a/include/clang/Lex/ModuleMap.h b/include/clang/Lex/ModuleMap.h
index 082408d..1c9c673 100644
--- a/include/clang/Lex/ModuleMap.h
+++ b/include/clang/Lex/ModuleMap.h
@@ -22,8 +22,8 @@
#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 "llvm/ADT/StringRef.h"
#include <string>
namespace clang {
@@ -33,6 +33,7 @@ class FileEntry;
class FileManager;
class DiagnosticConsumer;
class DiagnosticsEngine;
+class HeaderSearch;
class ModuleMapParser;
class ModuleMap {
@@ -40,6 +41,7 @@ class ModuleMap {
IntrusiveRefCntPtr<DiagnosticsEngine> Diags;
const LangOptions &LangOpts;
const TargetInfo *Target;
+ HeaderSearch &HeaderInfo;
/// \brief The directory used for Clang-supplied, builtin include headers,
/// such as "stdint.h".
@@ -104,13 +106,17 @@ class ModuleMap {
/// \brief The names of modules that cannot be inferred within this
/// directory.
- llvm::SmallVector<std::string, 2> ExcludedModules;
+ SmallVector<std::string, 2> ExcludedModules;
};
/// \brief A mapping from directories to information about inferring
/// framework modules from within those directories.
llvm::DenseMap<const DirectoryEntry *, InferredDirectory> InferredDirectories;
+ /// \brief Describes whether we haved parsed a particular file as a module
+ /// map.
+ llvm::DenseMap<const FileEntry *, bool> ParsedModuleMap;
+
friend class ModuleMapParser;
/// \brief Resolve the given export declaration into an actual export
@@ -127,8 +133,21 @@ class ModuleMap {
/// if the export could not be resolved.
Module::ExportDecl
resolveExport(Module *Mod, const Module::UnresolvedExportDecl &Unresolved,
- bool Complain);
-
+ bool Complain) const;
+
+ /// \brief Resolve the given module id to an actual module.
+ ///
+ /// \param Id The module-id to resolve.
+ ///
+ /// \param Mod The module in which we're resolving the module-id.
+ ///
+ /// \param Complain Whether this routine should complain about unresolvable
+ /// module-ids.
+ ///
+ /// \returns The resolved module, or null if the module-id could not be
+ /// resolved.
+ Module *resolveModuleId(const ModuleId &Id, Module *Mod, bool Complain) const;
+
public:
/// \brief Construct a new module map.
///
@@ -143,7 +162,8 @@ public:
///
/// \param Target The target for this translation unit.
ModuleMap(FileManager &FileMgr, const DiagnosticConsumer &DC,
- const LangOptions &LangOpts, const TargetInfo *Target);
+ const LangOptions &LangOpts, const TargetInfo *Target,
+ HeaderSearch &HeaderInfo);
/// \brief Destroy the module map.
///
@@ -157,6 +177,7 @@ public:
void setBuiltinIncludeDir(const DirectoryEntry *Dir) {
BuiltinIncludeDir = Dir;
}
+ const DirectoryEntry *getBuiltinIncludeDir() { return BuiltinIncludeDir; }
/// \brief Retrieve the module that owns the given header file, if any.
///
@@ -168,14 +189,14 @@ public:
/// \brief Determine whether the given header is part of a module
/// marked 'unavailable'.
- bool isHeaderInUnavailableModule(const FileEntry *Header);
+ bool isHeaderInUnavailableModule(const FileEntry *Header) const;
/// \brief Retrieve a module with the given name.
///
/// \param Name The name of the module to look up.
///
/// \returns The named module, if known; otherwise, returns null.
- Module *findModule(StringRef Name);
+ Module *findModule(StringRef Name) const;
/// \brief Retrieve a module with the given name using lexical name lookup,
/// starting at the given context.
@@ -186,7 +207,7 @@ public:
/// name lookup.
///
/// \returns The named module, if known; otherwise, returns null.
- Module *lookupModuleUnqualified(StringRef Name, Module *Context);
+ Module *lookupModuleUnqualified(StringRef Name, Module *Context) const;
/// \brief Retrieve a module with the given name within the given context,
/// using direct (qualified) name lookup.
@@ -197,7 +218,7 @@ public:
/// null, we will look for a top-level module.
///
/// \returns The named submodule, if known; otherwose, returns null.
- Module *lookupModuleQualified(StringRef Name, Module *Context);
+ Module *lookupModuleQualified(StringRef Name, Module *Context) const;
/// \brief Find a new module or submodule, or create it if it does not already
/// exist.
@@ -231,7 +252,7 @@ public:
/// \returns true if we are allowed to infer a framework module, and false
/// otherwise.
bool canInferFrameworkModule(const DirectoryEntry *ParentDir,
- StringRef Name, bool &IsSystem);
+ StringRef Name, bool &IsSystem) const;
/// \brief Infer the contents of a framework module map from the given
/// framework directory.
@@ -246,7 +267,7 @@ public:
///
/// \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);
+ const FileEntry *getContainingModuleMapFile(Module *Module) const;
/// \brief Resolve all of the unresolved exports in the given module.
///
@@ -258,7 +279,17 @@ public:
/// false otherwise.
bool resolveExports(Module *Mod, bool Complain);
- /// \brief Infers the (sub)module based on the given source location and
+ /// \brief Resolve all of the unresolved conflicts in the given module.
+ ///
+ /// \param Mod The module whose conflicts should be resolved.
+ ///
+ /// \param Complain Whether to emit diagnostics for failures.
+ ///
+ /// \returns true if any errors were encountered while resolving conflicts,
+ /// false otherwise.
+ bool resolveConflicts(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
diff --git a/include/clang/Lex/PPCallbacks.h b/include/clang/Lex/PPCallbacks.h
index 8ba02cc..96359a2 100644
--- a/include/clang/Lex/PPCallbacks.h
+++ b/include/clang/Lex/PPCallbacks.h
@@ -15,10 +15,10 @@
#ifndef LLVM_CLANG_LEX_PPCALLBACKS_H
#define LLVM_CLANG_LEX_PPCALLBACKS_H
+#include "clang/Basic/DiagnosticIDs.h"
+#include "clang/Basic/SourceLocation.h"
#include "clang/Lex/DirectoryLookup.h"
#include "clang/Lex/ModuleLoader.h"
-#include "clang/Basic/SourceLocation.h"
-#include "clang/Basic/DiagnosticIDs.h"
#include "llvm/ADT/StringRef.h"
#include <string>
@@ -26,7 +26,7 @@ namespace clang {
class SourceLocation;
class Token;
class IdentifierInfo;
- class MacroInfo;
+ class MacroDirective;
/// \brief This interface provides a way to observe the actions of the
/// preprocessor as it does its thing.
@@ -184,22 +184,25 @@ public:
/// \brief Called by Preprocessor::HandleMacroExpandedIdentifier when a
/// macro invocation is found.
- virtual void MacroExpands(const Token &MacroNameTok, const MacroInfo* MI,
+ virtual void MacroExpands(const Token &MacroNameTok, const MacroDirective *MD,
SourceRange Range) {
}
/// \brief Hook called whenever a macro definition is seen.
- virtual void MacroDefined(const Token &MacroNameTok, const MacroInfo *MI) {
+ virtual void MacroDefined(const Token &MacroNameTok,
+ const MacroDirective *MD) {
}
/// \brief Hook called whenever a macro \#undef is seen.
///
- /// MI is released immediately following this callback.
- virtual void MacroUndefined(const Token &MacroNameTok, const MacroInfo *MI) {
+ /// MD is released immediately following this callback.
+ virtual void MacroUndefined(const Token &MacroNameTok,
+ const MacroDirective *MD) {
}
/// \brief Hook called whenever the 'defined' operator is seen.
- virtual void Defined(const Token &MacroNameTok) {
+ /// \param MD The MacroDirective if the name was a macro, null otherwise.
+ virtual void Defined(const Token &MacroNameTok, const MacroDirective *MD) {
}
/// \brief Hook called when a source range is skipped.
@@ -228,13 +231,17 @@ public:
/// \brief Hook called whenever an \#ifdef is seen.
/// \param Loc the source location of the directive.
/// \param MacroNameTok Information on the token being tested.
- virtual void Ifdef(SourceLocation Loc, const Token &MacroNameTok) {
+ /// \param MD The MacroDirective if the name was a macro, null otherwise.
+ virtual void Ifdef(SourceLocation Loc, const Token &MacroNameTok,
+ const MacroDirective *MD) {
}
/// \brief Hook called whenever an \#ifndef is seen.
/// \param Loc the source location of the directive.
/// \param MacroNameTok Information on the token being tested.
- virtual void Ifndef(SourceLocation Loc, const Token &MacroNameTok) {
+ /// \param MD The MacroDirective if the name was a macro, null otherwise.
+ virtual void Ifndef(SourceLocation Loc, const Token &MacroNameTok,
+ const MacroDirective *MD) {
}
/// \brief Hook called whenever an \#else is seen.
@@ -346,25 +353,26 @@ public:
Second->PragmaDiagnostic(Loc, Namespace, mapping, Str);
}
- virtual void MacroExpands(const Token &MacroNameTok, const MacroInfo* MI,
+ virtual void MacroExpands(const Token &MacroNameTok, const MacroDirective *MD,
SourceRange Range) {
- First->MacroExpands(MacroNameTok, MI, Range);
- Second->MacroExpands(MacroNameTok, MI, Range);
+ First->MacroExpands(MacroNameTok, MD, Range);
+ Second->MacroExpands(MacroNameTok, MD, Range);
}
- virtual void MacroDefined(const Token &MacroNameTok, const MacroInfo *MI) {
- First->MacroDefined(MacroNameTok, MI);
- Second->MacroDefined(MacroNameTok, MI);
+ virtual void MacroDefined(const Token &MacroNameTok, const MacroDirective *MD) {
+ First->MacroDefined(MacroNameTok, MD);
+ Second->MacroDefined(MacroNameTok, MD);
}
- virtual void MacroUndefined(const Token &MacroNameTok, const MacroInfo *MI) {
- First->MacroUndefined(MacroNameTok, MI);
- Second->MacroUndefined(MacroNameTok, MI);
+ virtual void MacroUndefined(const Token &MacroNameTok,
+ const MacroDirective *MD) {
+ First->MacroUndefined(MacroNameTok, MD);
+ Second->MacroUndefined(MacroNameTok, MD);
}
- virtual void Defined(const Token &MacroNameTok) {
- First->Defined(MacroNameTok);
- Second->Defined(MacroNameTok);
+ virtual void Defined(const Token &MacroNameTok, const MacroDirective *MD) {
+ First->Defined(MacroNameTok, MD);
+ Second->Defined(MacroNameTok, MD);
}
virtual void SourceRangeSkipped(SourceRange Range) {
@@ -386,15 +394,17 @@ public:
}
/// \brief Hook called whenever an \#ifdef is seen.
- virtual void Ifdef(SourceLocation Loc, const Token &MacroNameTok) {
- First->Ifdef(Loc, MacroNameTok);
- Second->Ifdef(Loc, MacroNameTok);
+ virtual void Ifdef(SourceLocation Loc, const Token &MacroNameTok,
+ const MacroDirective *MD) {
+ First->Ifdef(Loc, MacroNameTok, MD);
+ Second->Ifdef(Loc, MacroNameTok, MD);
}
/// \brief Hook called whenever an \#ifndef is seen.
- virtual void Ifndef(SourceLocation Loc, const Token &MacroNameTok) {
- First->Ifndef(Loc, MacroNameTok);
- Second->Ifndef(Loc, MacroNameTok);
+ virtual void Ifndef(SourceLocation Loc, const Token &MacroNameTok,
+ const MacroDirective *MD) {
+ First->Ifndef(Loc, MacroNameTok, MD);
+ Second->Ifndef(Loc, MacroNameTok, MD);
}
/// \brief Hook called whenever an \#else is seen.
diff --git a/include/clang/Lex/PPConditionalDirectiveRecord.h b/include/clang/Lex/PPConditionalDirectiveRecord.h
new file mode 100644
index 0000000..b9a2252
--- /dev/null
+++ b/include/clang/Lex/PPConditionalDirectiveRecord.h
@@ -0,0 +1,102 @@
+//===--- PPConditionalDirectiveRecord.h - Preprocessing Directives-*- 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 PPConditionalDirectiveRecord class, which maintains
+// a record of conditional directive regions.
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_CLANG_LEX_PPCONDITIONALDIRECTIVERECORD_H
+#define LLVM_CLANG_LEX_PPCONDITIONALDIRECTIVERECORD_H
+
+#include "clang/Basic/SourceLocation.h"
+#include "clang/Lex/PPCallbacks.h"
+#include "llvm/ADT/SmallVector.h"
+#include <vector>
+
+namespace clang {
+
+/// \brief Records preprocessor conditional directive regions and allows
+/// querying in which region source locations belong to.
+class PPConditionalDirectiveRecord : public PPCallbacks {
+ SourceManager &SourceMgr;
+
+ SmallVector<SourceLocation, 6> CondDirectiveStack;
+
+ class CondDirectiveLoc {
+ SourceLocation Loc;
+ SourceLocation RegionLoc;
+
+ public:
+ CondDirectiveLoc(SourceLocation Loc, SourceLocation RegionLoc)
+ : Loc(Loc), RegionLoc(RegionLoc) {}
+
+ SourceLocation getLoc() const { return Loc; }
+ SourceLocation getRegionLoc() const { return RegionLoc; }
+
+ 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);
+
+public:
+ /// \brief Construct a new preprocessing record.
+ explicit PPConditionalDirectiveRecord(SourceManager &SM);
+
+ size_t getTotalMemory() const;
+
+ SourceManager &getSourceManager() const { return SourceMgr; }
+
+ /// \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 findConditionalDirectiveRegionLoc(LHS) !=
+ findConditionalDirectiveRegionLoc(RHS);
+ }
+
+ SourceLocation findConditionalDirectiveRegionLoc(SourceLocation Loc) const;
+
+private:
+ virtual void If(SourceLocation Loc, SourceRange ConditionRange);
+ virtual void Elif(SourceLocation Loc, SourceRange ConditionRange,
+ SourceLocation IfLoc);
+ virtual void Ifdef(SourceLocation Loc, const Token &MacroNameTok,
+ const MacroDirective *MD);
+ virtual void Ifndef(SourceLocation Loc, const Token &MacroNameTok,
+ const MacroDirective *MD);
+ virtual void Else(SourceLocation Loc, SourceLocation IfLoc);
+ virtual void Endif(SourceLocation Loc, SourceLocation IfLoc);
+};
+
+} // end namespace clang
+
+#endif // LLVM_CLANG_LEX_PPCONDITIONALDIRECTIVERECORD_H
diff --git a/include/clang/Lex/PPMutationListener.h b/include/clang/Lex/PPMutationListener.h
deleted file mode 100644
index 5319c66..0000000
--- a/include/clang/Lex/PPMutationListener.h
+++ /dev/null
@@ -1,43 +0,0 @@
-//===--- PPMutationListener.h - Preprocessor Mutation Interface -*- 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 PPMutationListener interface.
-//
-//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_LEX_PPTMUTATIONLISTENER_H
-#define LLVM_CLANG_LEX_PPTMUTATIONLISTENER_H
-
-#include "clang/Basic/SourceLocation.h"
-
-namespace clang {
-
-class MacroInfo;
-
-/// \brief A record that describes an update to a macro that was
-/// originally loaded to an AST file and has been modified within the
-/// current translation unit.
-struct MacroUpdate {
- /// \brief The source location at which this macro was #undef'd.
- SourceLocation UndefLoc;
-};
-
-/// \brief An abstract interface that should be implemented by
-/// listeners that want to be notified when a preprocessor entity gets
-/// modified after its initial creation.
-class PPMutationListener {
-public:
- virtual ~PPMutationListener();
-
- /// \brief A macro has been #undef'd.
- virtual void UndefinedMacro(MacroInfo *MI) { }
-};
-
-} // end namespace clang
-
-#endif
diff --git a/include/clang/Lex/PTHManager.h b/include/clang/Lex/PTHManager.h
index e64dbd8..fad0806 100644
--- a/include/clang/Lex/PTHManager.h
+++ b/include/clang/Lex/PTHManager.h
@@ -14,10 +14,10 @@
#ifndef LLVM_CLANG_PTHMANAGER_H
#define LLVM_CLANG_PTHMANAGER_H
-#include "clang/Lex/PTHLexer.h"
-#include "clang/Basic/LangOptions.h"
-#include "clang/Basic/IdentifierTable.h"
#include "clang/Basic/Diagnostic.h"
+#include "clang/Basic/IdentifierTable.h"
+#include "clang/Basic/LangOptions.h"
+#include "clang/Lex/PTHLexer.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/Support/Allocator.h"
#include <string>
diff --git a/include/clang/Lex/PreprocessingRecord.h b/include/clang/Lex/PreprocessingRecord.h
index 57e51b7..b13b2be 100644
--- a/include/clang/Lex/PreprocessingRecord.h
+++ b/include/clang/Lex/PreprocessingRecord.h
@@ -14,18 +14,19 @@
#ifndef LLVM_CLANG_LEX_PREPROCESSINGRECORD_H
#define LLVM_CLANG_LEX_PREPROCESSINGRECORD_H
-#include "clang/Lex/PPCallbacks.h"
-#include "clang/Basic/SourceLocation.h"
#include "clang/Basic/IdentifierTable.h"
-#include "llvm/ADT/SmallVector.h"
+#include "clang/Basic/SourceLocation.h"
+#include "clang/Lex/PPCallbacks.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/Optional.h"
+#include "llvm/ADT/SmallVector.h"
#include "llvm/Support/Allocator.h"
#include "llvm/Support/Compiler.h"
#include <vector>
namespace clang {
class IdentifierInfo;
+ class MacroInfo;
class PreprocessingRecord;
}
@@ -277,9 +278,9 @@ namespace clang {
/// \brief Optionally returns true or false if the preallocated preprocessed
/// entity with index \p Index came from file \p FID.
- virtual llvm::Optional<bool> isPreprocessedEntityInFileID(unsigned Index,
- FileID FID) {
- return llvm::Optional<bool>();
+ virtual Optional<bool> isPreprocessedEntityInFileID(unsigned Index,
+ FileID FID) {
+ return None;
}
};
@@ -303,44 +304,6 @@ 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
@@ -363,7 +326,7 @@ namespace clang {
}
/// \brief Mapping from MacroInfo structures to their definitions.
- llvm::DenseMap<const MacroInfo *, PPEntityID> MacroDefinitions;
+ llvm::DenseMap<const MacroInfo *, MacroDefinition *> MacroDefinitions;
/// \brief External source of preprocessed entities.
ExternalPreprocessingRecordSource *ExternalSource;
@@ -394,11 +357,11 @@ namespace clang {
unsigned allocateLoadedEntities(unsigned NumEntities);
/// \brief Register a new macro definition.
- void RegisterMacroDefinition(MacroInfo *Macro, PPEntityID PPID);
+ void RegisterMacroDefinition(MacroInfo *Macro, MacroDefinition *Def);
public:
/// \brief Construct a new preprocessing record.
- PreprocessingRecord(SourceManager &SM, bool RecordConditionalDirectives);
+ explicit PreprocessingRecord(SourceManager &SM);
/// \brief Allocate memory in the preprocessing record.
void *Allocate(unsigned Size, unsigned Align = 8) {
@@ -582,24 +545,6 @@ namespace clang {
/// \brief Add a new preprocessed entity to this record.
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);
@@ -613,10 +558,10 @@ namespace clang {
MacroDefinition *findMacroDefinition(const MacroInfo *MI);
private:
- virtual void MacroExpands(const Token &Id, const MacroInfo* MI,
+ virtual void MacroExpands(const Token &Id, const MacroDirective *MD,
SourceRange Range);
- virtual void MacroDefined(const Token &Id, const MacroInfo *MI);
- virtual void MacroUndefined(const Token &Id, const MacroInfo *MI);
+ virtual void MacroDefined(const Token &Id, const MacroDirective *MD);
+ virtual void MacroUndefined(const Token &Id, const MacroDirective *MD);
virtual void InclusionDirective(SourceLocation HashLoc,
const Token &IncludeTok,
StringRef FileName,
@@ -626,13 +571,15 @@ namespace clang {
StringRef SearchPath,
StringRef RelativePath,
const Module *Imported);
- 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);
+ virtual void Ifdef(SourceLocation Loc, const Token &MacroNameTok,
+ const MacroDirective *MD);
+ virtual void Ifndef(SourceLocation Loc, const Token &MacroNameTok,
+ const MacroDirective *MD);
+ /// \brief Hook called whenever the 'defined' operator is seen.
+ virtual void Defined(const Token &MacroNameTok, const MacroDirective *MD);
+
+ void addMacroExpansion(const Token &Id, const MacroInfo *MI,
+ SourceRange Range);
/// \brief Cached result of the last \see getPreprocessedEntitiesInRange
/// query.
diff --git a/include/clang/Lex/Preprocessor.h b/include/clang/Lex/Preprocessor.h
index e9095fb..7a912ec 100644
--- a/include/clang/Lex/Preprocessor.h
+++ b/include/clang/Lex/Preprocessor.h
@@ -14,23 +14,22 @@
#ifndef LLVM_CLANG_LEX_PREPROCESSOR_H
#define LLVM_CLANG_LEX_PREPROCESSOR_H
-#include "clang/Lex/MacroInfo.h"
-#include "clang/Lex/Lexer.h"
-#include "clang/Lex/PTHLexer.h"
-#include "clang/Lex/PPCallbacks.h"
-#include "clang/Lex/PPMutationListener.h"
-#include "clang/Lex/TokenLexer.h"
-#include "clang/Lex/PTHManager.h"
#include "clang/Basic/Builtins.h"
#include "clang/Basic/Diagnostic.h"
#include "clang/Basic/IdentifierTable.h"
#include "clang/Basic/SourceLocation.h"
+#include "clang/Lex/Lexer.h"
+#include "clang/Lex/MacroInfo.h"
+#include "clang/Lex/PPCallbacks.h"
+#include "clang/Lex/PTHLexer.h"
+#include "clang/Lex/PTHManager.h"
+#include "clang/Lex/TokenLexer.h"
+#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/IntrusiveRefCntPtr.h"
-#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/OwningPtr.h"
+#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
-#include "llvm/ADT/ArrayRef.h"
#include "llvm/Support/Allocator.h"
#include <vector>
@@ -84,7 +83,7 @@ public:
/// like the \#include stack, token expansion, etc.
///
class Preprocessor : public RefCountedBase<Preprocessor> {
- llvm::IntrusiveRefCntPtr<PreprocessorOptions> PPOpts;
+ IntrusiveRefCntPtr<PreprocessorOptions> PPOpts;
DiagnosticsEngine *Diags;
LangOptions &LangOpts;
const TargetInfo *Target;
@@ -160,6 +159,12 @@ class Preprocessor : public RefCountedBase<Preprocessor> {
/// \brief True if pragmas are enabled.
bool PragmasEnabled : 1;
+ /// \brief True if the current build action is a preprocessing action.
+ bool PreprocessedOutput : 1;
+
+ /// \brief True if we are currently preprocessing a #if or #elif directive
+ bool ParsingIfOrElifDirective;
+
/// \brief True if we are pre-expanding macro arguments.
bool InMacroArgPreExpansion;
@@ -215,8 +220,7 @@ class Preprocessor : public RefCountedBase<Preprocessor> {
SourceLocation ModuleImportLoc;
/// \brief The module import path that we're currently processing.
- llvm::SmallVector<std::pair<IdentifierInfo *, SourceLocation>, 2>
- ModuleImportPath;
+ SmallVector<std::pair<IdentifierInfo *, SourceLocation>, 2> ModuleImportPath;
/// \brief Whether the module import expectes an identifier next. Otherwise,
/// it expects a '.' or ';'.
@@ -291,24 +295,19 @@ class Preprocessor : public RefCountedBase<Preprocessor> {
/// encountered (e.g. a file is \#included, etc).
PPCallbacks *Callbacks;
- /// \brief Listener whose actions are invoked when an entity in the
- /// preprocessor (e.g., a macro) that was loaded from an AST file is
- /// later mutated.
- PPMutationListener *Listener;
-
struct MacroExpandsInfo {
Token Tok;
- MacroInfo *MI;
+ MacroDirective *MD;
SourceRange Range;
- MacroExpandsInfo(Token Tok, MacroInfo *MI, SourceRange Range)
- : Tok(Tok), MI(MI), Range(Range) { }
+ MacroExpandsInfo(Token Tok, MacroDirective *MD, SourceRange Range)
+ : Tok(Tok), MD(MD), Range(Range) { }
};
SmallVector<MacroExpandsInfo, 2> DelayedMacroExpandsCallbacks;
/// Macros - For each IdentifierInfo that was associated with a macro, we
/// keep a mapping to the history of all macro definitions and #undefs in
/// the reverse order (the latest one is in the head of the list).
- llvm::DenseMap<IdentifierInfo*, MacroInfo*> Macros;
+ llvm::DenseMap<const IdentifierInfo*, MacroDirective*> Macros;
friend class ASTReader;
/// \brief Macros that we want to warn because they are not used at the end
@@ -343,6 +342,9 @@ class Preprocessor : public RefCountedBase<Preprocessor> {
/// should use from the command line etc.
std::string Predefines;
+ /// \brief The file ID for the preprocessor predefines.
+ FileID PredefinesFileID;
+
/// TokenLexerCache - Cache macro expanders to reduce malloc traffic.
enum { TokenLexerCacheSize = 8 };
unsigned NumCachedTokenLexers;
@@ -396,7 +398,7 @@ private: // Cached tokens state.
MacroInfoChain *MICache;
public:
- Preprocessor(llvm::IntrusiveRefCntPtr<PreprocessorOptions> PPOpts,
+ Preprocessor(IntrusiveRefCntPtr<PreprocessorOptions> PPOpts,
DiagnosticsEngine &diags, LangOptions &opts,
const TargetInfo *target,
SourceManager &SM, HeaderSearch &Headers,
@@ -447,6 +449,11 @@ public:
/// \brief Retrieve the module loader associated with this preprocessor.
ModuleLoader &getModuleLoader() const { return TheModuleLoader; }
+ /// \brief True if we are currently preprocessing a #if or #elif directive
+ bool isParsingIfOrElifDirective() const {
+ return ParsingIfOrElifDirective;
+ }
+
/// SetCommentRetentionState - Control whether or not the preprocessor retains
/// comments in output.
void SetCommentRetentionState(bool KeepComments, bool KeepMacroComments) {
@@ -467,6 +474,16 @@ public:
return SuppressIncludeNotFoundError;
}
+ /// Sets whether the preprocessor is responsible for producing output or if
+ /// it is producing tokens to be consumed by Parse and Sema.
+ void setPreprocessedOutput(bool IsPreprocessedOutput) {
+ PreprocessedOutput = IsPreprocessedOutput;
+ }
+
+ /// Returns true if the preprocessor is responsible for generating output,
+ /// false if it is producing tokens to be consumed by Parse and Sema.
+ bool isPreprocessedOutput() const { return PreprocessedOutput; }
+
/// isCurrentLexer - Return true if we are lexing directly from the specified
/// lexer.
bool isCurrentLexer(const PreprocessorLexer *L) const {
@@ -483,6 +500,9 @@ public:
/// expansions going on at the time.
PreprocessorLexer *getCurrentFileLexer() const;
+ /// \brief Returns the file ID for the preprocessor predefines.
+ FileID getPredefinesFileID() const { return PredefinesFileID; }
+
/// getPPCallbacks/addPPCallbacks - Accessors for preprocessor callbacks.
/// Note that this class takes ownership of any PPCallbacks object given to
/// it.
@@ -493,53 +513,54 @@ public:
Callbacks = C;
}
- /// \brief Attach an preprocessor mutation listener to the preprocessor.
- ///
- /// The preprocessor mutation listener provides the ability to track
- /// modifications to the preprocessor entities committed after they were
- /// initially created.
- void setPPMutationListener(PPMutationListener *Listener) {
- this->Listener = Listener;
- }
-
- /// \brief Retrieve a pointer to the preprocessor mutation listener
- /// associated with this preprocessor, if any.
- PPMutationListener *getPPMutationListener() const { return Listener; }
-
- /// \brief Given an identifier, return the MacroInfo it is \#defined to
- /// or null if it isn't \#define'd.
- MacroInfo *getMacroInfo(IdentifierInfo *II) const {
+ /// \brief Given an identifier, return its latest MacroDirective if it is
+ // \#defined or null if it isn't \#define'd.
+ MacroDirective *getMacroDirective(IdentifierInfo *II) const {
if (!II->hasMacroDefinition())
return 0;
- MacroInfo *MI = getMacroInfoHistory(II);
- assert(MI->getUndefLoc().isInvalid() && "Macro is undefined!");
- return MI;
+ MacroDirective *MD = getMacroDirectiveHistory(II);
+ assert(MD->isDefined() && "Macro is undefined!");
+ return MD;
+ }
+
+ const MacroInfo *getMacroInfo(IdentifierInfo *II) const {
+ return const_cast<Preprocessor*>(this)->getMacroInfo(II);
+ }
+
+ MacroInfo *getMacroInfo(IdentifierInfo *II) {
+ if (MacroDirective *MD = getMacroDirective(II))
+ return MD->getMacroInfo();
+ return 0;
}
/// \brief Given an identifier, return the (probably #undef'd) MacroInfo
/// representing the most recent macro definition. One can iterate over all
/// previous macro definitions from it. This method should only be called for
/// identifiers that hadMacroDefinition().
- MacroInfo *getMacroInfoHistory(IdentifierInfo *II) const;
-
- /// \brief Specify a macro for this identifier.
- void setMacroInfo(IdentifierInfo *II, MacroInfo *MI);
- /// \brief Add a MacroInfo that was loaded from an AST file.
- void addLoadedMacroInfo(IdentifierInfo *II, MacroInfo *MI,
- MacroInfo *Hint = 0);
- /// \brief Make the given MacroInfo, that was loaded from an AST file and
- /// previously hidden, visible.
- void makeLoadedMacroInfoVisible(IdentifierInfo *II, MacroInfo *MI);
- /// \brief Undefine a macro for this identifier.
- void clearMacroInfo(IdentifierInfo *II);
+ MacroDirective *getMacroDirectiveHistory(const IdentifierInfo *II) const;
+
+ /// \brief Add a directive to the macro directive history for this identifier.
+ void appendMacroDirective(IdentifierInfo *II, MacroDirective *MD);
+ DefMacroDirective *appendDefMacroDirective(IdentifierInfo *II, MacroInfo *MI,
+ SourceLocation Loc,
+ bool isImported) {
+ DefMacroDirective *MD = AllocateDefMacroDirective(MI, Loc, isImported);
+ appendMacroDirective(II, MD);
+ return MD;
+ }
+ DefMacroDirective *appendDefMacroDirective(IdentifierInfo *II, MacroInfo *MI){
+ return appendDefMacroDirective(II, MI, MI->getDefinitionLoc(), false);
+ }
+ /// \brief Set a MacroDirective that was loaded from a PCH file.
+ void setLoadedMacroDirective(IdentifierInfo *II, MacroDirective *MD);
/// macro_iterator/macro_begin/macro_end - This allows you to walk the macro
/// history table. Currently defined macros have
/// IdentifierInfo::hasMacroDefinition() set and an empty
/// MacroInfo::getUndefLoc() at the head of the list.
- typedef llvm::DenseMap<IdentifierInfo*,
- MacroInfo*>::const_iterator macro_iterator;
+ typedef llvm::DenseMap<const IdentifierInfo *,
+ MacroDirective*>::const_iterator macro_iterator;
macro_iterator macro_begin(bool IncludeExternalMacros = true) const;
macro_iterator macro_end(bool IncludeExternalMacros = true) const;
@@ -611,7 +632,7 @@ public:
/// \brief Create a new preprocessing record, which will keep track of
/// all macro expansions, macro definitions, etc.
- void createPreprocessingRecord(bool RecordConditionalDirectives);
+ void createPreprocessingRecord();
/// EnterMainSourceFile - Enter the specified FileID as the main source file,
/// which implicitly adds the builtin defines etc.
@@ -696,6 +717,25 @@ public:
void LexAfterModuleImport(Token &Result);
+ /// \brief Lex a string literal, which may be the concatenation of multiple
+ /// string literals and may even come from macro expansion.
+ /// \returns true on success, false if a error diagnostic has been generated.
+ bool LexStringLiteral(Token &Result, std::string &String,
+ const char *DiagnosticTag, bool AllowMacroExpansion) {
+ if (AllowMacroExpansion)
+ Lex(Result);
+ else
+ LexUnexpandedToken(Result);
+ return FinishLexStringLiteral(Result, String, DiagnosticTag,
+ AllowMacroExpansion);
+ }
+
+ /// \brief Complete the lexing of a string literal where the first token has
+ /// already been lexed (see LexStringLiteral).
+ bool FinishLexStringLiteral(Token &Result, std::string &String,
+ const char *DiagnosticTag,
+ bool AllowMacroExpansion);
+
/// 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.
@@ -901,8 +941,8 @@ public:
/// "cleaning", e.g. if it contains trigraphs or escaped newlines
/// \param invalid If non-null, will be set \c true if an error occurs.
StringRef getSpelling(SourceLocation loc,
- SmallVectorImpl<char> &buffer,
- bool *invalid = 0) const {
+ SmallVectorImpl<char> &buffer,
+ bool *invalid = 0) const {
return Lexer::getSpelling(loc, buffer, SourceMgr, LangOpts, invalid);
}
@@ -939,6 +979,12 @@ public:
SmallVectorImpl<char> &Buffer,
bool *Invalid = 0) const;
+ /// \brief Relex the token at the specified location.
+ /// \returns true if there was a failure, false on success.
+ bool getRawToken(SourceLocation Loc, Token &Result) {
+ return Lexer::getRawToken(Loc, Result, SourceMgr, LangOpts);
+ }
+
/// getSpellingOfSingleCharacterNumericConstant - Tok is a numeric constant
/// with length 1, return the character.
char getSpellingOfSingleCharacterNumericConstant(const Token &Tok,
@@ -1143,8 +1189,9 @@ public:
/// \brief Allocate a new MacroInfo object with the provided SourceLocation.
MacroInfo *AllocateMacroInfo(SourceLocation L);
- /// \brief Allocate a new MacroInfo object which is clone of \p MI.
- MacroInfo *CloneMacroInfo(const MacroInfo &MI);
+ /// \brief Allocate a new MacroInfo object loaded from an AST file.
+ MacroInfo *AllocateDeserializedMacroInfo(SourceLocation L,
+ unsigned SubModuleID);
/// \brief Turn the specified lexer token into a fully checked and spelled
/// filename, e.g. as an operand of \#include.
@@ -1221,6 +1268,13 @@ private:
/// \brief Allocate a new MacroInfo object.
MacroInfo *AllocateMacroInfo();
+ DefMacroDirective *AllocateDefMacroDirective(MacroInfo *MI,
+ SourceLocation Loc,
+ bool isImported);
+ UndefMacroDirective *AllocateUndefMacroDirective(SourceLocation UndefLoc);
+ VisibilityMacroDirective *AllocateVisibilityMacroDirective(SourceLocation Loc,
+ bool isPublic);
+
/// \brief Release the specified MacroInfo for re-use.
///
/// This memory will be reused for allocating new MacroInfo objects.
@@ -1268,7 +1322,7 @@ private:
/// HandleMacroExpandedIdentifier - If an identifier token is read that is to
/// be expanded as a macro, handle it and return the next token as 'Tok'. If
/// the macro should not be expanded return true, otherwise return false.
- bool HandleMacroExpandedIdentifier(Token &Tok, MacroInfo *MI);
+ bool HandleMacroExpandedIdentifier(Token &Tok, MacroDirective *MD);
/// \brief Cache macro expanded tokens for TokenLexers.
//
@@ -1312,6 +1366,12 @@ private:
/// start getting tokens from it using the PTH cache.
void EnterSourceFileWithPTH(PTHLexer *PL, const DirectoryLookup *Dir);
+ /// \brief Set the file ID for the preprocessor predefines.
+ void setPredefinesFileID(FileID FID) {
+ assert(PredefinesFileID.isInvalid() && "PredefinesFileID already set!");
+ PredefinesFileID = FID;
+ }
+
/// IsFileLexer - Returns true if we are lexing from a file and not a
/// pragma or a macro.
static bool IsFileLexer(const Lexer* L, const PreprocessorLexer* P) {
@@ -1367,8 +1427,6 @@ private:
// Macro handling.
void HandleDefineDirective(Token &Tok);
void HandleUndefDirective(Token &Tok);
- void UndefineMacro(IdentifierInfo *II, MacroInfo *MI,
- SourceLocation UndefLoc);
// Conditional Inclusion.
void HandleIfdefDirective(Token &Tok, bool isIfndef,
diff --git a/include/clang/Lex/PreprocessorOptions.h b/include/clang/Lex/PreprocessorOptions.h
index e5fe373..eba2a13 100644
--- a/include/clang/Lex/PreprocessorOptions.h
+++ b/include/clang/Lex/PreprocessorOptions.h
@@ -10,14 +10,16 @@
#ifndef LLVM_CLANG_LEX_PREPROCESSOROPTIONS_H_
#define LLVM_CLANG_LEX_PREPROCESSOROPTIONS_H_
+#include "clang/Basic/SourceLocation.h"
#include "llvm/ADT/IntrusiveRefCntPtr.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/StringSet.h"
#include <cassert>
+#include <set>
#include <string>
#include <utility>
#include <vector>
-#include <set>
namespace llvm {
class MemoryBuffer;
@@ -39,23 +41,20 @@ enum ObjCXXARCStandardLibraryKind {
/// PreprocessorOptions - This class is used for passing the various options
/// used in preprocessor initialization to InitializePreprocessor().
-class PreprocessorOptions : public llvm::RefCountedBase<PreprocessorOptions> {
+class PreprocessorOptions : public RefCountedBase<PreprocessorOptions> {
public:
std::vector<std::pair<std::string, bool/*isUndef*/> > Macros;
std::vector<std::string> Includes;
std::vector<std::string> MacroIncludes;
- unsigned UsePredefines : 1; /// Initialize the preprocessor with the compiler
- /// and target specific predefines.
+ /// \brief Initialize the preprocessor with the compiler and target specific
+ /// predefines.
+ unsigned UsePredefines : 1;
+
+ /// \brief Whether we should maintain a detailed record of all macro
+ /// definitions and expansions.
+ unsigned DetailedRecord : 1;
- unsigned DetailedRecord : 1; /// Whether we should maintain a detailed
- /// record of all macro definitions and
- /// expansions.
- unsigned DetailedRecordConditionalDirectives : 1; /// Whether in the
- /// preprocessing record we should also keep
- /// track of locations of conditional directives
- /// in non-system files.
-
/// The implicit PCH included at the start of the translation unit, or empty.
std::string ImplicitPCHInclude;
@@ -119,14 +118,28 @@ public:
/// with support for lifetime-qualified pointers.
ObjCXXARCStandardLibraryKind ObjCXXARCStandardLibrary;
- /// \brief The path of modules being build, which is used to detect
- /// cycles in the module dependency graph as modules are being built.
- ///
- /// There is no way to set this value from the command line. If we ever need
- /// to do so (e.g., if on-demand module construction moves out-of-process),
- /// we can add a cc1-level option to do so.
- SmallVector<std::string, 2> ModuleBuildPath;
+ /// \brief Records the set of modules
+ class FailedModulesSet : public RefCountedBase<FailedModulesSet> {
+ llvm::StringSet<> Failed;
+
+ public:
+ bool hasAlreadyFailed(StringRef module) {
+ return Failed.count(module) > 0;
+ }
+
+ void addFailed(StringRef module) {
+ Failed.insert(module);
+ }
+ };
+ /// \brief The set of modules that failed to build.
+ ///
+ /// This pointer will be shared among all of the compiler instances created
+ /// to (re)build modules, so that once a module fails to build anywhere,
+ /// other instances will see that the module has failed and won't try to
+ /// build it again.
+ IntrusiveRefCntPtr<FailedModulesSet> FailedModules;
+
typedef std::vector<std::pair<std::string, std::string> >::iterator
remapped_file_iterator;
typedef std::vector<std::pair<std::string, std::string> >::const_iterator
@@ -163,7 +176,6 @@ public:
public:
PreprocessorOptions() : UsePredefines(true), DetailedRecord(false),
- DetailedRecordConditionalDirectives(false),
DisablePCHValidation(false),
AllowPCHWithCompilerErrors(false),
DumpDeserializedPCHDecls(false),
diff --git a/include/clang/Lex/Token.h b/include/clang/Lex/Token.h
index 50b86c8..bcbe9c9 100644
--- a/include/clang/Lex/Token.h
+++ b/include/clang/Lex/Token.h
@@ -14,10 +14,10 @@
#ifndef LLVM_CLANG_TOKEN_H
#define LLVM_CLANG_TOKEN_H
+#include "clang/Basic/OperatorKinds.h"
+#include "clang/Basic/SourceLocation.h"
#include "clang/Basic/TemplateKinds.h"
#include "clang/Basic/TokenKinds.h"
-#include "clang/Basic/SourceLocation.h"
-#include "clang/Basic/OperatorKinds.h"
#include <cstdlib>
namespace clang {
@@ -74,9 +74,10 @@ public:
StartOfLine = 0x01, // At start of line or only after whitespace.
LeadingSpace = 0x02, // Whitespace exists before this token.
DisableExpand = 0x04, // This identifier may never be macro expanded.
- NeedsCleaning = 0x08, // Contained an escaped newline or trigraph.
+ NeedsCleaning = 0x08, // Contained an escaped newline or trigraph.
LeadingEmptyMacro = 0x10, // Empty macro exists before this token.
- HasUDSuffix = 0x20 // This string or character literal has a ud-suffix.
+ HasUDSuffix = 0x20, // This string or character literal has a ud-suffix.
+ HasUCN = 0x40 // This identifier contains a UCN.
};
tok::TokenKind getKind() const { return (tok::TokenKind)Kind; }
@@ -257,6 +258,9 @@ public:
/// \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; }
+
+ /// Returns true if this token contains a universal character name.
+ bool hasUCN() const { return (Flags & HasUCN) ? true : false; }
};
/// \brief Information about the conditional stack (\#if directives)
OpenPOWER on IntegriCloud