summaryrefslogtreecommitdiff
path: root/include/clang/Lex
diff options
context:
space:
mode:
Diffstat (limited to 'include/clang/Lex')
-rw-r--r--include/clang/Lex/DirectoryLookup.h4
-rw-r--r--include/clang/Lex/HeaderMap.h72
-rw-r--r--include/clang/Lex/HeaderMapTypes.h43
-rw-r--r--include/clang/Lex/HeaderSearch.h20
-rw-r--r--include/clang/Lex/Lexer.h20
-rw-r--r--include/clang/Lex/LiteralSupport.h10
-rw-r--r--include/clang/Lex/MacroArgs.h2
-rw-r--r--include/clang/Lex/MacroInfo.h6
-rw-r--r--include/clang/Lex/ModuleMap.h33
-rw-r--r--include/clang/Lex/Preprocessor.h58
-rw-r--r--include/clang/Lex/Token.h43
11 files changed, 238 insertions, 73 deletions
diff --git a/include/clang/Lex/DirectoryLookup.h b/include/clang/Lex/DirectoryLookup.h
index 20c4bb03ab6e6..ee0af292e6fcc 100644
--- a/include/clang/Lex/DirectoryLookup.h
+++ b/include/clang/Lex/DirectoryLookup.h
@@ -151,6 +151,9 @@ public:
///
/// \param HS The header search instance to search with.
///
+ /// \param IncludeLoc the source location of the #include or #import
+ /// directive.
+ ///
/// \param SearchPath If not NULL, will be set to the search path relative
/// to which the file was found.
///
@@ -172,6 +175,7 @@ public:
/// a framework include ("Foo.h" -> "Foo/Foo.h"), set the new name to this
/// vector and point Filename to it.
const FileEntry *LookupFile(StringRef &Filename, HeaderSearch &HS,
+ SourceLocation IncludeLoc,
SmallVectorImpl<char> *SearchPath,
SmallVectorImpl<char> *RelativePath,
Module *RequestingModule,
diff --git a/include/clang/Lex/HeaderMap.h b/include/clang/Lex/HeaderMap.h
index 183361e4f8c0c..8466f1a24d52d 100644
--- a/include/clang/Lex/HeaderMap.h
+++ b/include/clang/Lex/HeaderMap.h
@@ -15,60 +15,74 @@
#define LLVM_CLANG_LEX_HEADERMAP_H
#include "clang/Basic/LLVM.h"
+#include "llvm/ADT/Optional.h"
#include "llvm/Support/Compiler.h"
+#include "llvm/Support/MemoryBuffer.h"
#include <memory>
-namespace llvm {
- class MemoryBuffer;
-}
namespace clang {
- class FileEntry;
- class FileManager;
- struct HMapBucket;
- struct HMapHeader;
-/// This class represents an Apple concept known as a 'header map'. To the
-/// \#include file resolution process, it basically acts like a directory of
-/// symlinks to files. Its advantages are that it is dense and more efficient
-/// to create and process than a directory of symlinks.
-class HeaderMap {
- HeaderMap(const HeaderMap &) = delete;
- void operator=(const HeaderMap &) = delete;
+class FileEntry;
+class FileManager;
+struct HMapBucket;
+struct HMapHeader;
+/// Implementation for \a HeaderMap that doesn't depend on \a FileManager.
+class HeaderMapImpl {
std::unique_ptr<const llvm::MemoryBuffer> FileBuffer;
bool NeedsBSwap;
- HeaderMap(std::unique_ptr<const llvm::MemoryBuffer> File, bool BSwap)
- : FileBuffer(std::move(File)), NeedsBSwap(BSwap) {}
public:
- /// HeaderMap::Create - This attempts to load the specified file as a header
- /// map. If it doesn't look like a HeaderMap, it gives up and returns null.
- static const HeaderMap *Create(const FileEntry *FE, FileManager &FM);
+ HeaderMapImpl(std::unique_ptr<const llvm::MemoryBuffer> File, bool NeedsBSwap)
+ : FileBuffer(std::move(File)), NeedsBSwap(NeedsBSwap) {}
- /// LookupFile - Check to see if the specified relative filename is located in
- /// this HeaderMap. If so, open it and return its FileEntry.
- /// If RawPath is not NULL and the file is found, RawPath will be set to the
- /// raw path at which the file was found in the file system. For example,
- /// for a search path ".." and a filename "../file.h" this would be
- /// "../../file.h".
- const FileEntry *LookupFile(StringRef Filename, FileManager &FM) const;
+ // Check for a valid header and extract the byte swap.
+ static bool checkHeader(const llvm::MemoryBuffer &File, bool &NeedsByteSwap);
/// If the specified relative filename is located in this HeaderMap return
/// the filename it is mapped to, otherwise return an empty StringRef.
StringRef lookupFilename(StringRef Filename,
SmallVectorImpl<char> &DestPath) const;
- /// getFileName - Return the filename of the headermap.
+ /// Return the filename of the headermap.
const char *getFileName() const;
- /// dump - Print the contents of this headermap to stderr.
+ /// Print the contents of this headermap to stderr.
void dump() const;
private:
unsigned getEndianAdjustedWord(unsigned X) const;
const HMapHeader &getHeader() const;
HMapBucket getBucket(unsigned BucketNo) const;
- const char *getString(unsigned StrTabIdx) const;
+
+ /// Look up the specified string in the string table. If the string index is
+ /// not valid, return None.
+ Optional<StringRef> getString(unsigned StrTabIdx) const;
+};
+
+/// This class represents an Apple concept known as a 'header map'. To the
+/// \#include file resolution process, it basically acts like a directory of
+/// symlinks to files. Its advantages are that it is dense and more efficient
+/// to create and process than a directory of symlinks.
+class HeaderMap : private HeaderMapImpl {
+ HeaderMap(std::unique_ptr<const llvm::MemoryBuffer> File, bool BSwap)
+ : HeaderMapImpl(std::move(File), BSwap) {}
+
+public:
+ /// This attempts to load the specified file as a header map. If it doesn't
+ /// look like a HeaderMap, it gives up and returns null.
+ static const HeaderMap *Create(const FileEntry *FE, FileManager &FM);
+
+ /// Check to see if the specified relative filename is located in this
+ /// HeaderMap. If so, open it and return its FileEntry. If RawPath is not
+ /// NULL and the file is found, RawPath will be set to the raw path at which
+ /// the file was found in the file system. For example, for a search path
+ /// ".." and a filename "../file.h" this would be "../../file.h".
+ const FileEntry *LookupFile(StringRef Filename, FileManager &FM) const;
+
+ using HeaderMapImpl::lookupFilename;
+ using HeaderMapImpl::getFileName;
+ using HeaderMapImpl::dump;
};
} // end namespace clang.
diff --git a/include/clang/Lex/HeaderMapTypes.h b/include/clang/Lex/HeaderMapTypes.h
new file mode 100644
index 0000000000000..fbaf4baee4077
--- /dev/null
+++ b/include/clang/Lex/HeaderMapTypes.h
@@ -0,0 +1,43 @@
+//===- HeaderMapTypes.h - Types for the header map format -------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_LEX_HEADERMAPTYPES_H
+#define LLVM_CLANG_LEX_HEADERMAPTYPES_H
+
+#include <cstdint>
+
+namespace clang {
+
+enum {
+ HMAP_HeaderMagicNumber = ('h' << 24) | ('m' << 16) | ('a' << 8) | 'p',
+ HMAP_HeaderVersion = 1,
+ HMAP_EmptyBucketKey = 0
+};
+
+struct HMapBucket {
+ uint32_t Key; // Offset (into strings) of key.
+ uint32_t Prefix; // Offset (into strings) of value prefix.
+ uint32_t Suffix; // Offset (into strings) of value suffix.
+};
+
+struct HMapHeader {
+ uint32_t Magic; // Magic word, also indicates byte order.
+ uint16_t Version; // Version number -- currently 1.
+ uint16_t Reserved; // Reserved for future use - zero for now.
+ uint32_t StringsOffset; // Offset to start of string pool.
+ uint32_t NumEntries; // Number of entries in the string table.
+ uint32_t NumBuckets; // Number of buckets (always a power of 2).
+ uint32_t MaxValueLength; // Length of longest result path (excluding nul).
+ // An array of 'NumBuckets' HMapBucket objects follows this header.
+ // Strings follow the buckets, at StringsOffset.
+};
+
+} // end namespace clang.
+
+#endif
diff --git a/include/clang/Lex/HeaderSearch.h b/include/clang/Lex/HeaderSearch.h
index 6d592e19c0682..7bac01ef3a4ce 100644
--- a/include/clang/Lex/HeaderSearch.h
+++ b/include/clang/Lex/HeaderSearch.h
@@ -241,8 +241,6 @@ class HeaderSearch {
unsigned NumMultiIncludeFileOptzn;
unsigned NumFrameworkLookups, NumSubFrameworkLookups;
- const LangOptions &LangOpts;
-
// HeaderSearch doesn't support default or copy construction.
HeaderSearch(const HeaderSearch&) = delete;
void operator=(const HeaderSearch&) = delete;
@@ -383,7 +381,7 @@ public:
ArrayRef<std::pair<const FileEntry *, const DirectoryEntry *>> Includers,
SmallVectorImpl<char> *SearchPath, SmallVectorImpl<char> *RelativePath,
Module *RequestingModule, ModuleMap::KnownHeader *SuggestedModule,
- bool SkipCache = false);
+ bool SkipCache = false, bool BuildSystemModule = false);
/// \brief Look up a subframework for the specified \#include file.
///
@@ -582,8 +580,9 @@ private:
/// \brief Look up the file with the specified name and determine its owning
/// module.
const FileEntry *
- getFileAndSuggestModule(StringRef FileName, const DirectoryEntry *Dir,
- bool IsSystemHeaderDir, Module *RequestingModule,
+ getFileAndSuggestModule(StringRef FileName, SourceLocation IncludeLoc,
+ const DirectoryEntry *Dir, bool IsSystemHeaderDir,
+ Module *RequestingModule,
ModuleMap::KnownHeader *SuggestedModule);
public:
@@ -634,13 +633,18 @@ public:
/// \brief Retrieve a uniqued framework name.
StringRef getUniqueFrameworkName(StringRef Framework);
+ /// \brief Suggest a path by which the specified file could be found, for
+ /// use in diagnostics to suggest a #include.
+ ///
+ /// \param IsSystem If non-null, filled in to indicate whether the suggested
+ /// path is relative to a system header directory.
+ std::string suggestPathToFileForDiagnostics(const FileEntry *File,
+ bool *IsSystem = nullptr);
+
void PrintStats();
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 {
diff --git a/include/clang/Lex/Lexer.h b/include/clang/Lex/Lexer.h
index 12565d0b14b63..830c25a2e4d29 100644
--- a/include/clang/Lex/Lexer.h
+++ b/include/clang/Lex/Lexer.h
@@ -410,6 +410,26 @@ public:
const SourceManager &SM,
const LangOptions &LangOpts);
+ /// \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.
+ ///
+ /// This differs from Lexer::getImmediateMacroName in that any macro argument
+ /// location will result in the topmost function macro that accepted it.
+ /// e.g.
+ /// \code
+ /// MAC1( MAC2(foo) )
+ /// \endcode
+ /// for location of 'foo' token, this function will return "MAC1" while
+ /// Lexer::getImmediateMacroName will return "MAC2".
+ static StringRef getImmediateMacroNameForDiagnostics(
+ SourceLocation Loc, const SourceManager &SM, const LangOptions &LangOpts);
+
/// \brief Compute the preamble of the given file.
///
/// The preamble of a file contains the initial comments, include directives,
diff --git a/include/clang/Lex/LiteralSupport.h b/include/clang/Lex/LiteralSupport.h
index d568614e2ae4e..5f946fc8337e5 100644
--- a/include/clang/Lex/LiteralSupport.h
+++ b/include/clang/Lex/LiteralSupport.h
@@ -19,6 +19,7 @@
#include "clang/Basic/LLVM.h"
#include "clang/Basic/TokenKinds.h"
#include "llvm/ADT/APFloat.h"
+#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/DataTypes.h"
@@ -61,8 +62,10 @@ public:
bool isUnsigned : 1;
bool isLong : 1; // This is *not* set for long long.
bool isLongLong : 1;
+ bool isHalf : 1; // 1.0h
bool isFloat : 1; // 1.0f
bool isImaginary : 1; // 1.0i
+ bool isFloat128 : 1; // 1.0q
uint8_t MicrosoftInteger; // Microsoft suffix extension i8, i16, i32, or i64.
bool isIntegerLiteral() const {
@@ -104,9 +107,16 @@ public:
private:
void ParseNumberStartingWithZero(SourceLocation TokLoc);
+ void ParseDecimalOrOctalCommon(SourceLocation TokLoc);
static bool isDigitSeparator(char C) { return C == '\''; }
+ /// \brief Determine whether the sequence of characters [Start, End) contains
+ /// any real digits (not digit separators).
+ bool containsDigits(const char *Start, const char *End) {
+ return Start != End && (Start + 1 != End || !isDigitSeparator(Start[0]));
+ }
+
enum CheckSeparatorKind { CSK_BeforeDigits, CSK_AfterDigits };
/// \brief Ensure that we don't have a digit separator here.
diff --git a/include/clang/Lex/MacroArgs.h b/include/clang/Lex/MacroArgs.h
index 243b143f7af6e..7b2a48561ff63 100644
--- a/include/clang/Lex/MacroArgs.h
+++ b/include/clang/Lex/MacroArgs.h
@@ -15,13 +15,13 @@
#define LLVM_CLANG_LEX_MACROARGS_H
#include "clang/Basic/LLVM.h"
+#include "clang/Lex/Token.h"
#include "llvm/ADT/ArrayRef.h"
#include <vector>
namespace clang {
class MacroInfo;
class Preprocessor;
- class Token;
class SourceLocation;
/// MacroArgs - An instance of this class captures information about
diff --git a/include/clang/Lex/MacroInfo.h b/include/clang/Lex/MacroInfo.h
index 320645e2380c9..6cc3b0bb26f2c 100644
--- a/include/clang/Lex/MacroInfo.h
+++ b/include/clang/Lex/MacroInfo.h
@@ -106,7 +106,7 @@ class MacroInfo {
bool IsWarnIfUnused : 1;
/// \brief Whether this macro info was loaded from an AST file.
- unsigned FromASTFile : 1;
+ bool FromASTFile : 1;
/// \brief Whether this macro was used as header guard.
bool UsedForHeaderGuard : 1;
@@ -318,13 +318,13 @@ protected:
unsigned MDKind : 2;
/// \brief True if the macro directive was loaded from a PCH file.
- bool IsFromPCH : 1;
+ unsigned IsFromPCH : 1;
// Used by VisibilityMacroDirective ----------------------------------------//
/// \brief Whether the macro has public visibility (when described in a
/// module).
- bool IsPublic : 1;
+ unsigned IsPublic : 1;
MacroDirective(Kind K, SourceLocation Loc)
: Previous(nullptr), Loc(Loc), MDKind(K), IsFromPCH(false),
diff --git a/include/clang/Lex/ModuleMap.h b/include/clang/Lex/ModuleMap.h
index 155943e5453c8..1e86f736983f6 100644
--- a/include/clang/Lex/ModuleMap.h
+++ b/include/clang/Lex/ModuleMap.h
@@ -50,6 +50,18 @@ public:
/// \param IsSystem Whether this is a module map from a system include path.
virtual void moduleMapFileRead(SourceLocation FileStart,
const FileEntry &File, bool IsSystem) {}
+
+ /// \brief Called when a header is added during module map parsing.
+ ///
+ /// \param Filename The header file itself.
+ virtual void moduleMapAddHeader(StringRef Filename) {}
+
+ /// \brief Called when an umbrella header is added during module map parsing.
+ ///
+ /// \param FileMgr FileManager instance
+ /// \param Header The umbrella header to collect.
+ virtual void moduleMapAddUmbrellaHeader(FileManager *FileMgr,
+ const FileEntry *Header) {}
};
class ModuleMap {
@@ -70,15 +82,10 @@ class ModuleMap {
/// These are always simple C language options.
LangOptions MMapLangOpts;
- // The module that we are building; related to \c LangOptions::CurrentModule.
- Module *CompilingModule;
-
-public:
- // The module that the .cc source file is associated with.
+ // The module that the main source file is associated with (the module
+ // named LangOpts::CurrentModule, if we've loaded it).
Module *SourceModule;
- std::string SourceModuleName;
-private:
/// \brief The top-level modules that are known.
llvm::StringMap<Module *> Modules;
@@ -130,6 +137,12 @@ public:
return getModule()->isAvailable();
}
+ /// \brief Whether this header is accessible from the specified module.
+ bool isAccessibleFrom(Module *M) const {
+ return !(getRole() & PrivateHeader) ||
+ (M && M->getTopLevelModule() == getModule()->getTopLevelModule());
+ }
+
// \brief Whether this known header is valid (i.e., it has an
// associated module).
explicit operator bool() const {
@@ -318,12 +331,18 @@ public:
///
/// \param RequestingModule The module including a file.
///
+ /// \param RequestingModuleIsModuleInterface \c true if the inclusion is in
+ /// the interface of RequestingModule, \c false if it's in the
+ /// implementation of RequestingModule. Value is ignored and
+ /// meaningless if RequestingModule is nullptr.
+ ///
/// \param FilenameLoc The location of the inclusion's filename.
///
/// \param Filename The included filename as written.
///
/// \param File The included file.
void diagnoseHeaderInclusion(Module *RequestingModule,
+ bool RequestingModuleIsModuleInterface,
SourceLocation FilenameLoc, StringRef Filename,
const FileEntry *File);
diff --git a/include/clang/Lex/Preprocessor.h b/include/clang/Lex/Preprocessor.h
index f6154b6a49cdf..30cc37f6f884f 100644
--- a/include/clang/Lex/Preprocessor.h
+++ b/include/clang/Lex/Preprocessor.h
@@ -32,6 +32,7 @@
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/TinyPtrVector.h"
#include "llvm/Support/Allocator.h"
+#include "llvm/Support/Registry.h"
#include <memory>
#include <vector>
@@ -507,9 +508,10 @@ class Preprocessor : public RefCountedBase<Preprocessor> {
/// \brief Information about a submodule that we're currently building.
struct BuildingSubmoduleInfo {
BuildingSubmoduleInfo(Module *M, SourceLocation ImportLoc,
- SubmoduleState *OuterSubmoduleState)
- : M(M), ImportLoc(ImportLoc), OuterSubmoduleState(OuterSubmoduleState) {
- }
+ SubmoduleState *OuterSubmoduleState,
+ unsigned OuterPendingModuleMacroNames)
+ : M(M), ImportLoc(ImportLoc), OuterSubmoduleState(OuterSubmoduleState),
+ OuterPendingModuleMacroNames(OuterPendingModuleMacroNames) {}
/// The module that we are building.
Module *M;
@@ -517,6 +519,8 @@ class Preprocessor : public RefCountedBase<Preprocessor> {
SourceLocation ImportLoc;
/// The previous SubmoduleState.
SubmoduleState *OuterSubmoduleState;
+ /// The number of pending module macro names when we started building this.
+ unsigned OuterPendingModuleMacroNames;
};
SmallVector<BuildingSubmoduleInfo, 8> BuildingSubmoduleStack;
@@ -541,6 +545,9 @@ class Preprocessor : public RefCountedBase<Preprocessor> {
/// The set of known macros exported from modules.
llvm::FoldingSet<ModuleMacro> ModuleMacros;
+ /// The names of potential module macros that we've not yet processed.
+ llvm::SmallVector<const IdentifierInfo*, 32> PendingModuleMacroNames;
+
/// The list of module macros, for each identifier, that are not overridden by
/// any other module macro.
llvm::DenseMap<const IdentifierInfo *, llvm::TinyPtrVector<ModuleMacro*>>
@@ -1018,10 +1025,20 @@ public:
/// If \p OwnsTokens is false, this method assumes that the specified stream
/// of tokens has a permanent owner somewhere, so they do not need to be
/// copied. If it is true, it assumes the array of tokens is allocated with
- /// \c new[] and must be freed.
+ /// \c new[] and the Preprocessor will delete[] it.
+private:
void EnterTokenStream(const Token *Toks, unsigned NumToks,
bool DisableMacroExpansion, bool OwnsTokens);
+public:
+ void EnterTokenStream(std::unique_ptr<Token[]> Toks, unsigned NumToks,
+ bool DisableMacroExpansion) {
+ EnterTokenStream(Toks.release(), NumToks, DisableMacroExpansion, true);
+ }
+ void EnterTokenStream(ArrayRef<Token> Toks, bool DisableMacroExpansion) {
+ EnterTokenStream(Toks.data(), Toks.size(), DisableMacroExpansion, false);
+ }
+
/// \brief Pop the current lexer/macro exp off the top of the lexer stack.
///
/// This should only be used in situations where the current state of the
@@ -1185,6 +1202,17 @@ public:
return CachedTokens[CachedLexPos-1].getLastLoc();
}
+ /// \brief Whether \p Tok is the most recent token (`CachedLexPos - 1`) in
+ /// CachedTokens.
+ bool IsPreviousCachedToken(const Token &Tok) const;
+
+ /// \brief Replace token in `CachedLexPos - 1` in CachedTokens by the tokens
+ /// in \p NewToks.
+ ///
+ /// Useful when a token needs to be split in smaller ones and CachedTokens
+ /// most recent token must to be updated to reflect that.
+ void ReplacePreviousCachedToken(ArrayRef<Token> NewToks);
+
/// \brief Replace the last token with an annotation token.
///
/// Like AnnotateCachedTokens(), this routine replaces an
@@ -1683,6 +1711,10 @@ private:
void EnterSubmodule(Module *M, SourceLocation ImportLoc);
void LeaveSubmodule();
+ /// Determine whether we need to create module macros for #defines in the
+ /// current context.
+ bool needModuleMacros() const;
+
/// Update the set of active module macros and ambiguity flag for a module
/// macro name.
void updateModuleMacroInfo(const IdentifierInfo *II, ModuleMacroInfo &Info);
@@ -1859,6 +1891,19 @@ public:
/// directly or indirectly.
Module *getModuleContainingLocation(SourceLocation Loc);
+ /// \brief We want to produce a diagnostic at location IncLoc concerning a
+ /// missing module import.
+ ///
+ /// \param IncLoc The location at which the missing import was detected.
+ /// \param MLoc A location within the desired module at which some desired
+ /// effect occurred (eg, where a desired entity was declared).
+ ///
+ /// \return A file that can be #included to import a module containing MLoc.
+ /// Null if no such file could be determined or if a #include is not
+ /// appropriate.
+ const FileEntry *getModuleHeaderToIncludeForDiagnostics(SourceLocation IncLoc,
+ SourceLocation MLoc);
+
private:
// Macro handling.
void HandleDefineDirective(Token &Tok, bool ImmediatelyAfterTopLevelIfndef);
@@ -1906,6 +1951,11 @@ public:
virtual bool HandleComment(Preprocessor &PP, SourceRange Comment) = 0;
};
+/// \brief Registry of pragma handlers added by plugins
+typedef llvm::Registry<PragmaHandler> PragmaHandlerRegistry;
+
} // end namespace clang
+extern template class llvm::Registry<clang::PragmaHandler>;
+
#endif
diff --git a/include/clang/Lex/Token.h b/include/clang/Lex/Token.h
index 7ba22b2f626c6..4393e205ffaf5 100644
--- a/include/clang/Lex/Token.h
+++ b/include/clang/Lex/Token.h
@@ -14,12 +14,10 @@
#ifndef LLVM_CLANG_LEX_TOKEN_H
#define LLVM_CLANG_LEX_TOKEN_H
-#include "clang/Basic/OperatorKinds.h"
#include "clang/Basic/SourceLocation.h"
-#include "clang/Basic/TemplateKinds.h"
#include "clang/Basic/TokenKinds.h"
#include "llvm/ADT/StringRef.h"
-#include <cstdlib>
+#include <cassert>
namespace clang {
@@ -69,8 +67,8 @@ class Token {
/// Flags - Bits we track about this token, members of the TokenFlags enum.
unsigned short Flags;
-public:
+public:
// Various flags set per token:
enum TokenFlags {
StartOfLine = 0x01, // At start of line or only after whitespace
@@ -85,6 +83,7 @@ public:
IgnoredComma = 0x80, // This comma is not a macro argument separator (MS).
StringifiedInMacro = 0x100, // This string or character literal is formed by
// macro stringizing or charizing operator.
+ CommaAfterElided = 0x200, // The comma following this token was elided (MS).
};
tok::TokenKind getKind() const { return Kind; }
@@ -235,6 +234,11 @@ public:
Flags |= Flag;
}
+ /// \brief Get the specified flag.
+ bool getFlag(TokenFlags Flag) const {
+ return (Flags & Flag) != 0;
+ }
+
/// \brief Unset the specified flag.
void clearFlag(TokenFlags Flag) {
Flags &= ~Flag;
@@ -258,17 +262,15 @@ public:
/// isAtStartOfLine - Return true if this token is at the start of a line.
///
- bool isAtStartOfLine() const { return (Flags & StartOfLine) ? true : false; }
+ bool isAtStartOfLine() const { return getFlag(StartOfLine); }
/// \brief Return true if this token has whitespace before it.
///
- bool hasLeadingSpace() const { return (Flags & LeadingSpace) ? true : false; }
+ bool hasLeadingSpace() const { return getFlag(LeadingSpace); }
/// \brief Return true if this identifier token should never
/// be expanded in the future, due to C99 6.10.3.4p2.
- bool isExpandDisabled() const {
- return (Flags & DisableExpand) ? true : false;
- }
+ bool isExpandDisabled() const { return getFlag(DisableExpand); }
/// \brief Return true if we have an ObjC keyword identifier.
bool isObjCAtKeyword(tok::ObjCKeywordKind objcKey) const;
@@ -277,26 +279,25 @@ public:
tok::ObjCKeywordKind getObjCKeywordID() const;
/// \brief Return true if this token has trigraphs or escaped newlines in it.
- bool needsCleaning() const { return (Flags & NeedsCleaning) ? true : false; }
+ bool needsCleaning() const { return getFlag(NeedsCleaning); }
/// \brief Return true if this token has an empty macro before it.
///
- bool hasLeadingEmptyMacro() const {
- return (Flags & LeadingEmptyMacro) ? true : false;
- }
+ bool hasLeadingEmptyMacro() const { return getFlag(LeadingEmptyMacro); }
/// \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; }
+ bool hasUDSuffix() const { return getFlag(HasUDSuffix); }
/// Returns true if this token contains a universal character name.
- bool hasUCN() const { return (Flags & HasUCN) ? true : false; }
+ bool hasUCN() const { return getFlag(HasUCN); }
/// Returns true if this token is formed by macro by stringizing or charizing
/// operator.
- bool stringifiedInMacro() const {
- return (Flags & StringifiedInMacro) ? true : false;
- }
+ bool stringifiedInMacro() const { return getFlag(StringifiedInMacro); }
+
+ /// Returns true if the comma after this token was elided.
+ bool commaAfterElided() const { return getFlag(CommaAfterElided); }
};
/// \brief Information about the conditional stack (\#if directives)
@@ -318,11 +319,11 @@ struct PPConditionalInfo {
bool FoundElse;
};
-} // end namespace clang
+} // end namespace clang
namespace llvm {
template <>
struct isPodLike<clang::Token> { static const bool value = true; };
-} // end namespace llvm
+} // end namespace llvm
-#endif
+#endif // LLVM_CLANG_LEX_TOKEN_H