diff options
Diffstat (limited to 'include/clang/Lex')
-rw-r--r-- | include/clang/Lex/DirectoryLookup.h | 10 | ||||
-rw-r--r-- | include/clang/Lex/HeaderSearch.h | 65 | ||||
-rw-r--r-- | include/clang/Lex/HeaderSearchOptions.h | 8 | ||||
-rw-r--r-- | include/clang/Lex/LexDiagnostic.h | 2 | ||||
-rw-r--r-- | include/clang/Lex/Lexer.h | 69 | ||||
-rw-r--r-- | include/clang/Lex/LiteralSupport.h | 20 | ||||
-rw-r--r-- | include/clang/Lex/MacroInfo.h | 4 | ||||
-rw-r--r-- | include/clang/Lex/ModuleLoader.h | 4 | ||||
-rw-r--r-- | include/clang/Lex/ModuleMap.h | 86 | ||||
-rw-r--r-- | include/clang/Lex/MultipleIncludeOpt.h | 56 | ||||
-rw-r--r-- | include/clang/Lex/PPCallbacks.h | 95 | ||||
-rw-r--r-- | include/clang/Lex/PPConditionalDirectiveRecord.h | 5 | ||||
-rw-r--r-- | include/clang/Lex/PTHLexer.h | 2 | ||||
-rw-r--r-- | include/clang/Lex/PreprocessingRecord.h | 3 | ||||
-rw-r--r-- | include/clang/Lex/Preprocessor.h | 79 | ||||
-rw-r--r-- | include/clang/Lex/PreprocessorLexer.h | 6 | ||||
-rw-r--r-- | include/clang/Lex/Token.h | 9 | ||||
-rw-r--r-- | include/clang/Lex/TokenLexer.h | 4 |
18 files changed, 403 insertions, 124 deletions
diff --git a/include/clang/Lex/DirectoryLookup.h b/include/clang/Lex/DirectoryLookup.h index 261dfab..dff3e8c 100644 --- a/include/clang/Lex/DirectoryLookup.h +++ b/include/clang/Lex/DirectoryLookup.h @@ -16,6 +16,7 @@ #include "clang/Basic/LLVM.h" #include "clang/Basic/SourceManager.h" +#include "clang/Lex/ModuleMap.h" namespace clang { class HeaderMap; @@ -129,6 +130,11 @@ public: return (SrcMgr::CharacteristicKind)DirCharacteristic; } + /// \brief Whether this describes a system header directory. + bool isSystemHeaderDirectory() const { + return getDirCharacteristic() != SrcMgr::C_User; + } + /// \brief Whether this header map is building a framework or not. bool isIndexHeaderMap() const { return isHeaderMap() && IsIndexHeaderMap; @@ -158,7 +164,7 @@ public: const FileEntry *LookupFile(StringRef Filename, HeaderSearch &HS, SmallVectorImpl<char> *SearchPath, SmallVectorImpl<char> *RelativePath, - Module **SuggestedModule, + ModuleMap::KnownHeader *SuggestedModule, bool &InUserSpecifiedSystemFramework) const; private: @@ -166,7 +172,7 @@ private: StringRef Filename, HeaderSearch &HS, SmallVectorImpl<char> *SearchPath, SmallVectorImpl<char> *RelativePath, - Module **SuggestedModule, + ModuleMap::KnownHeader *SuggestedModule, bool &InUserSpecifiedSystemHeader) const; }; diff --git a/include/clang/Lex/HeaderSearch.h b/include/clang/Lex/HeaderSearch.h index 8a5a798..fb1a8620 100644 --- a/include/clang/Lex/HeaderSearch.h +++ b/include/clang/Lex/HeaderSearch.h @@ -53,6 +53,13 @@ struct HeaderFileInfo { /// \brief Whether this header is part of a module. unsigned isModuleHeader : 1; + + /// \brief Whether this header is part of the module that we are building. + unsigned isCompilingModuleHeader : 1; + + /// \brief Whether this header is part of the module that we are building. + /// This is an instance of ModuleMap::ModuleHeaderRole. + unsigned HeaderRole : 2; /// \brief Whether this structure is considered to already have been /// "resolved", meaning that it was loaded from the external source. @@ -93,8 +100,9 @@ struct HeaderFileInfo { HeaderFileInfo() : isImport(false), isPragmaOnce(false), DirInfo(SrcMgr::C_User), - External(false), isModuleHeader(false), Resolved(false), - IndexHeaderMapHeader(false), + External(false), isModuleHeader(false), isCompilingModuleHeader(false), + HeaderRole(ModuleMap::NormalHeader), + Resolved(false), IndexHeaderMapHeader(false), NumIncludes(0), ControllingMacroID(0), ControllingMacro(0) {} /// \brief Retrieve the controlling macro for this header file, if @@ -107,6 +115,16 @@ struct HeaderFileInfo { return isImport || isPragmaOnce || NumIncludes || ControllingMacro || ControllingMacroID; } + + /// \brief Get the HeaderRole properly typed. + ModuleMap::ModuleHeaderRole getHeaderRole() const { + return static_cast<ModuleMap::ModuleHeaderRole>(HeaderRole); + } + + /// \brief Set the HeaderRole properly typed. + void setHeaderRole(ModuleMap::ModuleHeaderRole Role) { + HeaderRole = Role; + } }; /// \brief An external source of header file information, which may supply @@ -222,7 +240,7 @@ class HeaderSearch { public: HeaderSearch(IntrusiveRefCntPtr<HeaderSearchOptions> HSOpts, - FileManager &FM, DiagnosticsEngine &Diags, + SourceManager &SourceMgr, DiagnosticsEngine &Diags, const LangOptions &LangOpts, const TargetInfo *Target); ~HeaderSearch(); @@ -261,7 +279,7 @@ public: /// \brief Checks whether the map exists or not. bool HasIncludeAliasMap() const { - return IncludeAliases; + return IncludeAliases.isValid(); } /// \brief Map the source include name to the dest include name. @@ -354,7 +372,7 @@ public: const FileEntry *CurFileEnt, SmallVectorImpl<char> *SearchPath, SmallVectorImpl<char> *RelativePath, - Module **SuggestedModule, + ModuleMap::KnownHeader *SuggestedModule, bool SkipCache = false); /// \brief Look up a subframework for the specified \#include file. @@ -368,7 +386,7 @@ public: const FileEntry *RelativeFileEnt, SmallVectorImpl<char> *SearchPath, SmallVectorImpl<char> *RelativePath, - Module **SuggestedModule); + ModuleMap::KnownHeader *SuggestedModule); /// \brief Look up the specified framework name in our framework cache. /// \returns The DirectoryEntry it is in if we know, null otherwise. @@ -405,7 +423,9 @@ public: } /// \brief Mark the specified file as part of a module. - void MarkFileModuleHeader(const FileEntry *File); + void MarkFileModuleHeader(const FileEntry *File, + ModuleMap::ModuleHeaderRole Role, + bool IsCompiledModuleHeader); /// \brief Increment the count for the number of times the specified /// FileEntry has been entered. @@ -422,6 +442,11 @@ public: getFileInfo(File).ControllingMacro = ControllingMacro; } + /// \brief Return true if this is the first time encountering this header. + bool FirstTimeLexingFile(const FileEntry *File) { + return getFileInfo(File).NumIncludes == 1; + } + /// \brief Determine whether this file is intended to be safe from /// multiple inclusions, e.g., it has \#pragma once or a controlling /// macro. @@ -471,25 +496,33 @@ public: /// /// \param Root The "root" directory, at which we should stop looking for /// module maps. - bool hasModuleMap(StringRef Filename, const DirectoryEntry *Root); + /// + /// \param IsSystem Whether the directories we're looking at are system + /// header directories. + bool hasModuleMap(StringRef Filename, const DirectoryEntry *Root, + bool IsSystem); /// \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) const; + ModuleMap::KnownHeader findModuleForHeader(const FileEntry *File) const; /// \brief Read the contents of the given module map file. /// /// \param File The module map file. + /// \param IsSystem Whether this file is in a system header directory. /// /// \returns true if an error occurred, false otherwise. - bool loadModuleMapFile(const FileEntry *File); + bool loadModuleMapFile(const FileEntry *File, bool IsSystem); /// \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(SmallVectorImpl<Module *> &Modules); - + + /// \brief Load all known, top-level system modules. + void loadTopLevelSystemModules(); + private: /// \brief Retrieve a module with the given name, which may be part of the /// given framework. @@ -516,9 +549,6 @@ public: unsigned header_file_size() const { return FileInfo.size(); } - // Used by ASTReader. - void setHeaderFileInfoForUID(HeaderFileInfo HFI, unsigned UID); - /// \brief Return the HeaderFileInfo structure for the specified FileEntry. const HeaderFileInfo &getFileInfo(const FileEntry *FE) const { return const_cast<HeaderSearch*>(this)->getFileInfo(FE); @@ -577,18 +607,21 @@ private: /// /// \param DirName The name of the directory where we will look for a module /// map file. + /// \param IsSystem Whether this is a system header directory. /// /// \returns The result of attempting to load the module map file from the /// named directory. - LoadModuleMapResult loadModuleMapFile(StringRef DirName); + LoadModuleMapResult loadModuleMapFile(StringRef DirName, bool IsSystem); /// \brief Try to load the module map file in the given directory. /// /// \param Dir The directory where we will look for a module map file. + /// \param IsSystem Whether this is a system header directory. /// /// \returns The result of attempting to load the module map file from the /// named directory. - LoadModuleMapResult loadModuleMapFile(const DirectoryEntry *Dir); + LoadModuleMapResult loadModuleMapFile(const DirectoryEntry *Dir, + bool IsSystem); /// \brief Return the HeaderFileInfo structure for the specified FileEntry. HeaderFileInfo &getFileInfo(const FileEntry *FE); diff --git a/include/clang/Lex/HeaderSearchOptions.h b/include/clang/Lex/HeaderSearchOptions.h index afce5ba..0b21c0d 100644 --- a/include/clang/Lex/HeaderSearchOptions.h +++ b/include/clang/Lex/HeaderSearchOptions.h @@ -95,6 +95,9 @@ public: /// Note: Only used for testing! unsigned DisableModuleHash : 1; + /// \brief Interpret module maps. This option is implied by full modules. + unsigned ModuleMaps : 1; + /// \brief The interval (in seconds) between pruning operations. /// /// This operation is expensive, because it requires Clang to walk through @@ -117,6 +120,9 @@ public: /// of computing the module hash. llvm::SetVector<std::string> ModulesIgnoreMacros; + /// \brief The set of user-provided module-map-files. + llvm::SetVector<std::string> ModuleMapFiles; + /// Include the compiler builtin includes. unsigned UseBuiltinIncludes : 1; @@ -134,7 +140,7 @@ public: public: HeaderSearchOptions(StringRef _Sysroot = "/") - : Sysroot(_Sysroot), DisableModuleHash(0), + : Sysroot(_Sysroot), DisableModuleHash(0), ModuleMaps(0), ModuleCachePruneInterval(7*24*60*60), ModuleCachePruneAfter(31*24*60*60), UseBuiltinIncludes(true), diff --git a/include/clang/Lex/LexDiagnostic.h b/include/clang/Lex/LexDiagnostic.h index 41b9396..85424aa 100644 --- a/include/clang/Lex/LexDiagnostic.h +++ b/include/clang/Lex/LexDiagnostic.h @@ -16,7 +16,7 @@ namespace clang { namespace diag { enum { #define DIAG(ENUM,FLAGS,DEFAULT_MAPPING,DESC,GROUP,\ - SFINAE,ACCESS,NOWERROR,SHOWINSYSHEADER,CATEGORY) ENUM, + SFINAE,NOWERROR,SHOWINSYSHEADER,CATEGORY) ENUM, #define LEXSTART #include "clang/Basic/DiagnosticLexKinds.inc" #undef DIAG diff --git a/include/clang/Lex/Lexer.h b/include/clang/Lex/Lexer.h index cb4f57f..f456fa9 100644 --- a/include/clang/Lex/Lexer.h +++ b/include/clang/Lex/Lexer.h @@ -80,6 +80,12 @@ class Lexer : public PreprocessorLexer { // line" flag set on it. bool IsAtStartOfLine; + bool IsAtPhysicalStartOfLine; + + bool HasLeadingSpace; + + bool HasLeadingEmptyMacro; + // CurrentConflictMarkerState - The kind of conflict marker we are handling. ConflictMarkerKind CurrentConflictMarkerState; @@ -127,31 +133,21 @@ public: /// from. Currently this is only used by _Pragma handling. SourceLocation getFileLoc() const { return FileLoc; } +private: /// Lex - Return the next token in the file. If this is the end of file, it /// return the tok::eof token. This implicitly involves the preprocessor. - void Lex(Token &Result) { - // Start a new token. - Result.startToken(); - - // NOTE, any changes here should also change code after calls to - // Preprocessor::HandleDirective - if (IsAtStartOfLine) { - Result.setFlag(Token::StartOfLine); - IsAtStartOfLine = false; - } - - // Get a token. Note that this may delete the current lexer if the end of - // file is reached. - LexTokenInternal(Result); - } + bool Lex(Token &Result); +public: /// isPragmaLexer - Returns true if this Lexer is being used to lex a pragma. bool isPragmaLexer() const { return Is_PragmaLexer; } +private: /// IndirectLex - An indirect call to 'Lex' that can be invoked via /// the PreprocessorLexer interface. void IndirectLex(Token &Result) { Lex(Result); } +public: /// LexFromRawLexer - Lex a token from a designated raw lexer (one with no /// associated preprocessor object. Return true if the 'next character to /// read' pointer points at the end of the lexer buffer, false otherwise. @@ -202,7 +198,10 @@ public: /// lexer has nothing to reset to. void resetExtendedTokenMode(); - const char *getBufferStart() const { return BufferStart; } + /// Gets source code buffer. + StringRef getBuffer() const { + return StringRef(BufferStart, BufferEnd - BufferStart); + } /// ReadToEndOfLine - Read the rest of the current preprocessor line as an /// uninterpreted string. This switches the lexer out of directive mode. @@ -285,7 +284,8 @@ public: /// \returns true if there was a failure, false on success. static bool getRawToken(SourceLocation Loc, Token &Result, const SourceManager &SM, - const LangOptions &LangOpts); + const LangOptions &LangOpts, + bool IgnoreWhiteSpace = false); /// \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 @@ -443,12 +443,14 @@ private: /// LexTokenInternal - Internal interface to lex a preprocessing token. Called /// by Lex. /// - void LexTokenInternal(Token &Result); + bool LexTokenInternal(Token &Result, bool TokAtPhysicalStartOfLine); + + bool CheckUnicodeWhitespace(Token &Result, uint32_t C, const char *CurPtr); /// 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); + bool 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 @@ -566,23 +568,28 @@ private: void SkipBytes(unsigned Bytes, bool StartOfLine); - const char *LexUDSuffix(Token &Result, const char *CurPtr); - + void PropagateLineStartLeadingSpaceInfo(Token &Result); + + const char *LexUDSuffix(Token &Result, const char *CurPtr, + bool IsStringLiteral); + // Helper functions to lex the remainder of a token of the specific type. - void LexIdentifier (Token &Result, const char *CurPtr); - void LexNumericConstant (Token &Result, const char *CurPtr); - void LexStringLiteral (Token &Result, const char *CurPtr, + bool LexIdentifier (Token &Result, const char *CurPtr); + bool LexNumericConstant (Token &Result, const char *CurPtr); + bool LexStringLiteral (Token &Result, const char *CurPtr, tok::TokenKind Kind); - void LexRawStringLiteral (Token &Result, const char *CurPtr, + bool LexRawStringLiteral (Token &Result, const char *CurPtr, tok::TokenKind Kind); - void LexAngledStringLiteral(Token &Result, const char *CurPtr); - void LexCharConstant (Token &Result, const char *CurPtr, + bool LexAngledStringLiteral(Token &Result, const char *CurPtr); + bool LexCharConstant (Token &Result, const char *CurPtr, tok::TokenKind Kind); bool LexEndOfFile (Token &Result, const char *CurPtr); - - bool SkipWhitespace (Token &Result, const char *CurPtr); - bool SkipLineComment (Token &Result, const char *CurPtr); - bool SkipBlockComment (Token &Result, const char *CurPtr); + bool SkipWhitespace (Token &Result, const char *CurPtr, + bool &TokAtPhysicalStartOfLine); + bool SkipLineComment (Token &Result, const char *CurPtr, + bool &TokAtPhysicalStartOfLine); + bool SkipBlockComment (Token &Result, const char *CurPtr, + bool &TokAtPhysicalStartOfLine); bool SaveLineComment (Token &Result, const char *CurPtr); bool IsStartOfConflictMarker(const char *CurPtr); diff --git a/include/clang/Lex/LiteralSupport.h b/include/clang/Lex/LiteralSupport.h index b1430cc..64d5aa2 100644 --- a/include/clang/Lex/LiteralSupport.h +++ b/include/clang/Lex/LiteralSupport.h @@ -79,6 +79,8 @@ public: return SuffixBegin - ThisTokBegin; } + static bool isValidUDSuffix(const LangOptions &LangOpts, StringRef Suffix); + unsigned getRadix() const { return radix; } /// GetIntegerValue - Convert this numeric literal value to an APInt that @@ -98,10 +100,18 @@ private: void ParseNumberStartingWithZero(SourceLocation TokLoc); + static bool isDigitSeparator(char C) { return C == '\''; } + + enum CheckSeparatorKind { CSK_BeforeDigits, CSK_AfterDigits }; + + /// \brief Ensure that we don't have a digit separator here. + void checkSeparator(SourceLocation TokLoc, const char *Pos, + CheckSeparatorKind IsAfterDigits); + /// 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 && isHexDigit(*ptr)) + while (ptr != ThisTokEnd && (isHexDigit(*ptr) || isDigitSeparator(*ptr))) ptr++; return ptr; } @@ -109,7 +119,8 @@ private: /// SkipOctalDigits - Read and skip over any octal digits, up to End. /// Return a pointer to the first non-hex digit or End. const char *SkipOctalDigits(const char *ptr) { - while (ptr != ThisTokEnd && ((*ptr >= '0') && (*ptr <= '7'))) + while (ptr != ThisTokEnd && + ((*ptr >= '0' && *ptr <= '7') || isDigitSeparator(*ptr))) ptr++; return ptr; } @@ -117,7 +128,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) || isDigitSeparator(*ptr))) ptr++; return ptr; } @@ -125,7 +136,8 @@ private: /// SkipBinaryDigits - Read and skip over any binary digits, up to End. /// Return a pointer to the first non-binary digit or End. const char *SkipBinaryDigits(const char *ptr) { - while (ptr != ThisTokEnd && (*ptr == '0' || *ptr == '1')) + while (ptr != ThisTokEnd && + (*ptr == '0' || *ptr == '1' || isDigitSeparator(*ptr))) ptr++; return ptr; } diff --git a/include/clang/Lex/MacroInfo.h b/include/clang/Lex/MacroInfo.h index 64323b7..8cb370e 100644 --- a/include/clang/Lex/MacroInfo.h +++ b/include/clang/Lex/MacroInfo.h @@ -251,7 +251,7 @@ public: return ReplacementTokens[Tok]; } - typedef SmallVector<Token, 8>::const_iterator tokens_iterator; + typedef SmallVectorImpl<Token>::const_iterator tokens_iterator; tokens_iterator tokens_begin() const { return ReplacementTokens.begin(); } tokens_iterator tokens_end() const { return ReplacementTokens.end(); } bool tokens_empty() const { return ReplacementTokens.empty(); } @@ -421,7 +421,7 @@ public: bool isValid() const { return DefDirective != 0; } bool isInvalid() const { return !isValid(); } - operator bool() const { return isValid(); } + LLVM_EXPLICIT operator bool() const { return isValid(); } inline DefInfo getPreviousDefinition(bool AllowHidden = false); const DefInfo getPreviousDefinition(bool AllowHidden = false) const { diff --git a/include/clang/Lex/ModuleLoader.h b/include/clang/Lex/ModuleLoader.h index 3acf915..254ab36 100644 --- a/include/clang/Lex/ModuleLoader.h +++ b/include/clang/Lex/ModuleLoader.h @@ -54,6 +54,8 @@ public: /// then loading that module. class ModuleLoader { public: + ModuleLoader() : HadFatalFailure(false) {} + virtual ~ModuleLoader(); /// \brief Attempt to load the given module. @@ -85,6 +87,8 @@ public: Module::NameVisibilityKind Visibility, SourceLocation ImportLoc, bool Complain) = 0; + + bool HadFatalFailure; }; } diff --git a/include/clang/Lex/ModuleMap.h b/include/clang/Lex/ModuleMap.h index dc75f18..3a17157 100644 --- a/include/clang/Lex/ModuleMap.h +++ b/include/clang/Lex/ModuleMap.h @@ -37,7 +37,7 @@ class HeaderSearch; class ModuleMapParser; class ModuleMap { - SourceManager *SourceMgr; + SourceManager &SourceMgr; IntrusiveRefCntPtr<DiagnosticsEngine> Diags; const LangOptions &LangOpts; const TargetInfo *Target; @@ -52,37 +52,64 @@ 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. + Module *SourceModule; + std::string SourceModuleName; + +private: /// \brief The top-level modules that are known. llvm::StringMap<Module *> Modules; +public: + /// \brief Describes the role of a module header. + enum ModuleHeaderRole { + /// \brief This header is normally included in the module. + NormalHeader, + /// \brief This header is included but private. + PrivateHeader, + /// \brief This header is explicitly excluded from the module. + ExcludedHeader + // Caution: Adding an enumerator needs other changes. + // Adjust the number of bits for KnownHeader::Storage. + // Adjust the bitfield HeaderFileInfo::HeaderRole size. + // Adjust the HeaderFileInfoTrait::ReadData streaming. + // Adjust the HeaderFileInfoTrait::EmitData streaming. + }; + /// \brief A header that is known to reside within a given module, /// whether it was included or excluded. class KnownHeader { - llvm::PointerIntPair<Module *, 1, bool> Storage; + llvm::PointerIntPair<Module *, 2, ModuleHeaderRole> Storage; public: - KnownHeader() : Storage(0, false) { } - KnownHeader(Module *M, bool Excluded) : Storage(M, Excluded) { } + KnownHeader() : Storage(0, NormalHeader) { } + KnownHeader(Module *M, ModuleHeaderRole Role) : Storage(M, Role) { } /// \brief Retrieve the module the header is stored in. Module *getModule() const { return Storage.getPointer(); } - /// \brief Whether this header is explicitly excluded from the module. - bool isExcluded() const { return Storage.getInt(); } + /// \brief The role of this header within the module. + ModuleHeaderRole getRole() const { return Storage.getInt(); } /// \brief Whether this header is available in the module. bool isAvailable() const { - return !isExcluded() && getModule()->isAvailable(); + return getRole() != ExcludedHeader && getModule()->isAvailable(); } // \brief Whether this known header is valid (i.e., it has an // associated module). - operator bool() const { return Storage.getPointer() != 0; } + LLVM_EXPLICIT operator bool() const { return Storage.getPointer() != 0; } }; - typedef llvm::DenseMap<const FileEntry *, KnownHeader> HeadersMap; +private: + typedef llvm::DenseMap<const FileEntry *, SmallVector<KnownHeader, 1> > + HeadersMap; - /// \brief Mapping from each header to the module that owns the contents of the + /// \brief Mapping from each header to the module that owns the contents of /// that header. HeadersMap Headers; @@ -151,9 +178,9 @@ class ModuleMap { public: /// \brief Construct a new module map. /// - /// \param FileMgr The file manager used to find module files and headers. - /// This file manager should be shared with the header-search mechanism, since - /// they will refer to the same headers. + /// \param SourceMgr The source manager used to find module files and headers. + /// This source manager should be shared with the header-search mechanism, + /// since they will refer to the same headers. /// /// \param DC A diagnostic consumer that will be cloned for use in generating /// diagnostics. @@ -161,7 +188,7 @@ public: /// \param LangOpts Language options for this translation unit. /// /// \param Target The target for this translation unit. - ModuleMap(FileManager &FileMgr, DiagnosticConsumer &DC, + ModuleMap(SourceManager &SourceMgr, DiagnosticConsumer &DC, const LangOptions &LangOpts, const TargetInfo *Target, HeaderSearch &HeaderInfo); @@ -182,9 +209,15 @@ public: /// /// \param File The header file that is likely to be included. /// - /// \returns The module that owns the given header file, or null to indicate + /// \param RequestingModule Specifies the module the header is intended to be + /// used from. Used to disambiguate if a header is present in multiple + /// modules. + /// + /// \returns The module KnownHeader, which provides the module that owns the + /// given header file. The KnownHeader is default constructed to indicate /// that no module owns this header file. - Module *findModuleForHeader(const FileEntry *File); + KnownHeader findModuleForHeader(const FileEntry *File, + Module *RequestingModule = NULL); /// \brief Determine whether the given header is part of a module /// marked 'unavailable'. @@ -278,6 +311,16 @@ public: /// false otherwise. bool resolveExports(Module *Mod, bool Complain); + /// \brief Resolve all of the unresolved uses in the given module. + /// + /// \param Mod The module whose uses should be resolved. + /// + /// \param Complain Whether to emit diagnostics for failures. + /// + /// \returns true if any errors were encountered while resolving uses, + /// false otherwise. + bool resolveUses(Module *Mod, bool Complain); + /// \brief Resolve all of the unresolved conflicts in the given module. /// /// \param Mod The module whose conflicts should be resolved. @@ -307,17 +350,20 @@ public: void setUmbrellaDir(Module *Mod, const DirectoryEntry *UmbrellaDir); /// \brief Adds this header to the given module. - /// \param Excluded Whether this header is explicitly excluded from the - /// module; otherwise, it's included in the module. - void addHeader(Module *Mod, const FileEntry *Header, bool Excluded); + /// \param Role The role of the header wrt the module. + void addHeader(Module *Mod, const FileEntry *Header, + ModuleHeaderRole Role); /// \brief Parse the given module map file, and record any modules we /// encounter. /// /// \param File The file to be parsed. /// + /// \param IsSystem Whether this module map file is in a system header + /// directory, and therefore should be considered a system module. + /// /// \returns true if an error occurred, false otherwise. - bool parseModuleMapFile(const FileEntry *File); + bool parseModuleMapFile(const FileEntry *File, bool IsSystem); /// \brief Dump the contents of the module map, for debugging purposes. void dump(); diff --git a/include/clang/Lex/MultipleIncludeOpt.h b/include/clang/Lex/MultipleIncludeOpt.h index a2a5a77..b532bf8 100644 --- a/include/clang/Lex/MultipleIncludeOpt.h +++ b/include/clang/Lex/MultipleIncludeOpt.h @@ -15,6 +15,8 @@ #ifndef LLVM_CLANG_MULTIPLEINCLUDEOPT_H #define LLVM_CLANG_MULTIPLEINCLUDEOPT_H +#include "clang/Basic/SourceLocation.h" + namespace clang { class IdentifierInfo; @@ -32,6 +34,11 @@ class MultipleIncludeOpt { /// \#endif can be easily detected. bool ReadAnyTokens; + /// ImmediatelyAfterTopLevelIfndef - This is true when the only tokens + /// processed in the file so far is an #ifndef and an identifier. Used in + /// the detection of header guards in a file. + bool ImmediatelyAfterTopLevelIfndef; + /// ReadAnyTokens - This is set to false when a file is first opened and true /// any time a token is returned to the client or a (non-multiple-include) /// directive is parsed. When the final #endif is parsed this is reset back @@ -42,11 +49,36 @@ class MultipleIncludeOpt { /// TheMacro - The controlling macro for a file, if valid. /// const IdentifierInfo *TheMacro; + + /// DefinedMacro - The macro defined right after TheMacro, if any. + const IdentifierInfo *DefinedMacro; + + SourceLocation MacroLoc; + SourceLocation DefinedLoc; public: MultipleIncludeOpt() { ReadAnyTokens = false; + ImmediatelyAfterTopLevelIfndef = false; DidMacroExpansion = false; TheMacro = 0; + DefinedMacro = 0; + } + + SourceLocation GetMacroLocation() const { + return MacroLoc; + } + + SourceLocation GetDefinedLocation() const { + return DefinedLoc; + } + + void resetImmediatelyAfterTopLevelIfndef() { + ImmediatelyAfterTopLevelIfndef = false; + } + + void SetDefinedMacro(IdentifierInfo *M, SourceLocation Loc) { + DefinedMacro = M; + DefinedLoc = Loc; } /// Invalidate - Permanently mark this file as not being suitable for the @@ -55,6 +87,8 @@ public: // If we have read tokens but have no controlling macro, the state-machine // below can never "accept". ReadAnyTokens = true; + ImmediatelyAfterTopLevelIfndef = false; + DefinedMacro = 0; TheMacro = 0; } @@ -63,8 +97,17 @@ public: /// the "ifndef x" would count as reading tokens. bool getHasReadAnyTokensVal() const { return ReadAnyTokens; } + /// getImmediatelyAfterTopLevelIfndef - returns true if the last directive + /// was an #ifndef at the beginning of the file. + bool getImmediatelyAfterTopLevelIfndef() const { + return ImmediatelyAfterTopLevelIfndef; + } + // If a token is read, remember that we have seen a side-effect in this file. - void ReadToken() { ReadAnyTokens = true; } + void ReadToken() { + ReadAnyTokens = true; + ImmediatelyAfterTopLevelIfndef = false; + } /// ExpandedMacro - When a macro is expanded with this lexer as the current /// buffer, this method is called to disable the MIOpt if needed. @@ -77,7 +120,7 @@ public: /// ensures that this is only called if there are no tokens read before the /// \#ifndef. The caller is required to do this, because reading the \#if /// line obviously reads in in tokens. - void EnterTopLevelIFNDEF(const IdentifierInfo *M) { + void EnterTopLevelIfndef(const IdentifierInfo *M, SourceLocation Loc) { // If the macro is already set, this is after the top-level #endif. if (TheMacro) return Invalidate(); @@ -91,7 +134,9 @@ public: // Remember that we're in the #if and that we have the macro. ReadAnyTokens = true; + ImmediatelyAfterTopLevelIfndef = true; TheMacro = M; + MacroLoc = Loc; } /// \brief Invoked when a top level conditional (except \#ifndef) is found. @@ -111,6 +156,7 @@ public: // At this point, we haven't "read any tokens" but we do have a controlling // macro. ReadAnyTokens = false; + ImmediatelyAfterTopLevelIfndef = false; } /// \brief Once the entire file has been lexed, if there is a controlling @@ -122,6 +168,12 @@ public: return TheMacro; return 0; } + + /// \brief If the ControllingMacro is followed by a macro definition, return + /// the macro that was defined. + const IdentifierInfo *GetDefinedMacro() const { + return DefinedMacro; + } }; } // end namespace clang diff --git a/include/clang/Lex/PPCallbacks.h b/include/clang/Lex/PPCallbacks.h index db2ecd2..0e11218 100644 --- a/include/clang/Lex/PPCallbacks.h +++ b/include/clang/Lex/PPCallbacks.h @@ -19,6 +19,7 @@ #include "clang/Basic/SourceLocation.h" #include "clang/Lex/DirectoryLookup.h" #include "clang/Lex/ModuleLoader.h" +#include "clang/Lex/Pragma.h" #include "llvm/ADT/StringRef.h" #include <string> @@ -155,11 +156,23 @@ public: virtual void Ident(SourceLocation Loc, const std::string &str) { } + /// \brief Callback invoked when start reading any pragma directive. + virtual void PragmaDirective(SourceLocation Loc, + PragmaIntroducerKind Introducer) { + } + /// \brief Callback invoked when a \#pragma comment directive is read. virtual void PragmaComment(SourceLocation Loc, const IdentifierInfo *Kind, const std::string &Str) { } + /// \brief Callback invoked when a \#pragma detect_mismatch directive is + /// read. + virtual void PragmaDetectMismatch(SourceLocation Loc, + const std::string &Name, + const std::string &Value) { + } + /// \brief Callback invoked when a \#pragma clang __debug directive is read. /// \param Loc The location of the debug directive. /// \param DebugType The identifier following __debug. @@ -204,6 +217,26 @@ public: diag::Mapping mapping, StringRef Str) { } + /// \brief Called when an OpenCL extension is either disabled or + /// enabled with a pragma. + virtual void PragmaOpenCLExtension(SourceLocation NameLoc, + const IdentifierInfo *Name, + SourceLocation StateLoc, unsigned State) { + } + + /// \brief Callback invoked when a \#pragma warning directive is read. + virtual void PragmaWarning(SourceLocation Loc, StringRef WarningSpec, + ArrayRef<int> Ids) { + } + + /// \brief Callback invoked when a \#pragma warning(push) directive is read. + virtual void PragmaWarningPush(SourceLocation Loc, int Level) { + } + + /// \brief Callback invoked when a \#pragma warning(pop) directive is read. + virtual void PragmaWarningPop(SourceLocation Loc) { + } + /// \brief Called by Preprocessor::HandleMacroExpandedIdentifier when a /// macro invocation is found. virtual void MacroExpands(const Token &MacroNameTok, const MacroDirective *MD, @@ -224,7 +257,8 @@ public: /// \brief Hook called whenever the 'defined' operator is seen. /// \param MD The MacroDirective if the name was a macro, null otherwise. - virtual void Defined(const Token &MacroNameTok, const MacroDirective *MD) { + virtual void Defined(const Token &MacroNameTok, const MacroDirective *MD, + SourceRange Range) { } /// \brief Hook called when a source range is skipped. @@ -236,18 +270,21 @@ public: /// \brief Hook called whenever an \#if is seen. /// \param Loc the source location of the directive. /// \param ConditionRange The SourceRange of the expression being tested. + /// \param ConditionValue The evaluated value of the condition. /// // FIXME: better to pass in a list (or tree!) of Tokens. - virtual void If(SourceLocation Loc, SourceRange ConditionRange) { + virtual void If(SourceLocation Loc, SourceRange ConditionRange, + bool ConditionValue) { } /// \brief Hook called whenever an \#elif is seen. /// \param Loc the source location of the directive. /// \param ConditionRange The SourceRange of the expression being tested. + /// \param ConditionValue The evaluated value of the condition. /// \param IfLoc the source location of the \#if/\#ifdef/\#ifndef directive. // FIXME: better to pass in a list (or tree!) of Tokens. virtual void Elif(SourceLocation Loc, SourceRange ConditionRange, - SourceLocation IfLoc) { + bool ConditionValue, SourceLocation IfLoc) { } /// \brief Hook called whenever an \#ifdef is seen. @@ -352,6 +389,13 @@ public: Second->PragmaComment(Loc, Kind, Str); } + virtual void PragmaDetectMismatch(SourceLocation Loc, + const std::string &Name, + const std::string &Value) { + First->PragmaDetectMismatch(Loc, Name, Value); + Second->PragmaDetectMismatch(Loc, Name, Value); + } + virtual void PragmaMessage(SourceLocation Loc, StringRef Namespace, PragmaMessageKind Kind, StringRef Str) { First->PragmaMessage(Loc, Namespace, Kind, Str); @@ -376,6 +420,29 @@ public: Second->PragmaDiagnostic(Loc, Namespace, mapping, Str); } + virtual void PragmaOpenCLExtension(SourceLocation NameLoc, + const IdentifierInfo *Name, + SourceLocation StateLoc, unsigned State) { + First->PragmaOpenCLExtension(NameLoc, Name, StateLoc, State); + Second->PragmaOpenCLExtension(NameLoc, Name, StateLoc, State); + } + + virtual void PragmaWarning(SourceLocation Loc, StringRef WarningSpec, + ArrayRef<int> Ids) { + First->PragmaWarning(Loc, WarningSpec, Ids); + Second->PragmaWarning(Loc, WarningSpec, Ids); + } + + virtual void PragmaWarningPush(SourceLocation Loc, int Level) { + First->PragmaWarningPush(Loc, Level); + Second->PragmaWarningPush(Loc, Level); + } + + virtual void PragmaWarningPop(SourceLocation Loc) { + First->PragmaWarningPop(Loc); + Second->PragmaWarningPop(Loc); + } + virtual void MacroExpands(const Token &MacroNameTok, const MacroDirective *MD, SourceRange Range, const MacroArgs *Args) { First->MacroExpands(MacroNameTok, MD, Range, Args); @@ -393,9 +460,10 @@ public: Second->MacroUndefined(MacroNameTok, MD); } - virtual void Defined(const Token &MacroNameTok, const MacroDirective *MD) { - First->Defined(MacroNameTok, MD); - Second->Defined(MacroNameTok, MD); + virtual void Defined(const Token &MacroNameTok, const MacroDirective *MD, + SourceRange Range) { + First->Defined(MacroNameTok, MD, Range); + Second->Defined(MacroNameTok, MD, Range); } virtual void SourceRangeSkipped(SourceRange Range) { @@ -404,16 +472,17 @@ public: } /// \brief Hook called whenever an \#if is seen. - virtual void If(SourceLocation Loc, SourceRange ConditionRange) { - First->If(Loc, ConditionRange); - Second->If(Loc, ConditionRange); + virtual void If(SourceLocation Loc, SourceRange ConditionRange, + bool ConditionValue) { + First->If(Loc, ConditionRange, ConditionValue); + Second->If(Loc, ConditionRange, ConditionValue); } - /// \brief Hook called whenever an \#if is seen. + /// \brief Hook called whenever an \#elif is seen. virtual void Elif(SourceLocation Loc, SourceRange ConditionRange, - SourceLocation IfLoc) { - First->Elif(Loc, ConditionRange, IfLoc); - Second->Elif(Loc, ConditionRange, IfLoc); + bool ConditionValue, SourceLocation IfLoc) { + First->Elif(Loc, ConditionRange, ConditionValue, IfLoc); + Second->Elif(Loc, ConditionRange, ConditionValue, IfLoc); } /// \brief Hook called whenever an \#ifdef is seen. diff --git a/include/clang/Lex/PPConditionalDirectiveRecord.h b/include/clang/Lex/PPConditionalDirectiveRecord.h index b9a2252..54a132d 100644 --- a/include/clang/Lex/PPConditionalDirectiveRecord.h +++ b/include/clang/Lex/PPConditionalDirectiveRecord.h @@ -86,9 +86,10 @@ public: SourceLocation findConditionalDirectiveRegionLoc(SourceLocation Loc) const; private: - virtual void If(SourceLocation Loc, SourceRange ConditionRange); + virtual void If(SourceLocation Loc, SourceRange ConditionRange, + bool ConditionValue); virtual void Elif(SourceLocation Loc, SourceRange ConditionRange, - SourceLocation IfLoc); + bool ConditionValue, SourceLocation IfLoc); virtual void Ifdef(SourceLocation Loc, const Token &MacroNameTok, const MacroDirective *MD); virtual void Ifndef(SourceLocation Loc, const Token &MacroNameTok, diff --git a/include/clang/Lex/PTHLexer.h b/include/clang/Lex/PTHLexer.h index a9276e8..d748bc1 100644 --- a/include/clang/Lex/PTHLexer.h +++ b/include/clang/Lex/PTHLexer.h @@ -68,7 +68,7 @@ public: ~PTHLexer() {} /// Lex - Return the next token. - void Lex(Token &Tok); + bool Lex(Token &Tok); void getEOF(Token &Tok); diff --git a/include/clang/Lex/PreprocessingRecord.h b/include/clang/Lex/PreprocessingRecord.h index db74352..2584340 100644 --- a/include/clang/Lex/PreprocessingRecord.h +++ b/include/clang/Lex/PreprocessingRecord.h @@ -576,7 +576,8 @@ namespace clang { 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); + virtual void Defined(const Token &MacroNameTok, const MacroDirective *MD, + SourceRange Range); void addMacroExpansion(const Token &Id, const MacroInfo *MI, SourceRange Range); diff --git a/include/clang/Lex/Preprocessor.h b/include/clang/Lex/Preprocessor.h index c598177..223fd47 100644 --- a/include/clang/Lex/Preprocessor.h +++ b/include/clang/Lex/Preprocessor.h @@ -20,6 +20,7 @@ #include "clang/Basic/SourceLocation.h" #include "clang/Lex/Lexer.h" #include "clang/Lex/MacroInfo.h" +#include "clang/Lex/ModuleMap.h" #include "clang/Lex/PPCallbacks.h" #include "clang/Lex/PTHLexer.h" #include "clang/Lex/PTHManager.h" @@ -221,7 +222,10 @@ class Preprocessor : public RefCountedBase<Preprocessor> { /// \brief The module import path that we're currently processing. SmallVector<std::pair<IdentifierInfo *, SourceLocation>, 2> ModuleImportPath; - + + /// \brief Whether the last token we lexed was an '@'. + bool LastTokenWasAt; + /// \brief Whether the module import expectes an identifier next. Otherwise, /// it expects a '.' or ';'. bool ModuleImportExpectsIdentifier; @@ -457,6 +461,10 @@ public: /// \brief Retrieve the module loader associated with this preprocessor. ModuleLoader &getModuleLoader() const { return TheModuleLoader; } + bool hadModuleLoaderFatalFailure() const { + return TheModuleLoader.HadFatalFailure; + } + /// \brief True if we are currently preprocessing a #if or #elif directive bool isParsingIfOrElifDirective() const { return ParsingIfOrElifDirective; @@ -711,17 +719,8 @@ public: /// caching of tokens is on. bool isBacktrackEnabled() const { return !BacktrackPositions.empty(); } - /// Lex - To lex a token from the preprocessor, just pull a token from the - /// current lexer or macro object. - void Lex(Token &Result) { - switch (CurLexerKind) { - case CLK_Lexer: CurLexer->Lex(Result); break; - case CLK_PTHLexer: CurPTHLexer->Lex(Result); break; - case CLK_TokenLexer: CurTokenLexer->Lex(Result); break; - case CLK_CachingLexer: CachingLex(Result); break; - case CLK_LexAfterModuleImport: LexAfterModuleImport(Result); break; - } - } + /// Lex - Lex the next token for this preprocessor. + void Lex(Token &Result); void LexAfterModuleImport(Token &Result); @@ -828,6 +827,13 @@ public: AnnotatePreviousCachedTokens(Tok); } + /// Get the location of the last cached token, suitable for setting the end + /// location of an annotation token. + SourceLocation getLastCachedTokenLocation() const { + assert(CachedLexPos != 0); + return CachedTokens[CachedLexPos-1].getLocation(); + } + /// \brief Replace the last token with an annotation token. /// /// Like AnnotateCachedTokens(), this routine replaces an @@ -989,8 +995,9 @@ public: /// \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); + bool getRawToken(SourceLocation Loc, Token &Result, + bool IgnoreWhiteSpace = false) { + return Lexer::getRawToken(Loc, Result, SourceMgr, LangOpts, IgnoreWhiteSpace); } /// getSpellingOfSingleCharacterNumericConstant - Tok is a numeric constant @@ -1155,7 +1162,10 @@ public: /// identifier and has filled in the tokens IdentifierInfo member. This /// callback potentially macro expands it or turns it into a named token (like /// 'for'). - void HandleIdentifier(Token &Identifier); + /// + /// \returns true if we actually computed a token, false if we need to + /// lex again. + bool HandleIdentifier(Token &Identifier); /// HandleEndOfFile - This callback is invoked when the lexer hits the end of @@ -1216,12 +1226,12 @@ public: /// /// Returns null on failure. \p isAngled indicates whether the file /// reference is for system \#include's or not (i.e. using <> instead of ""). - const FileEntry *LookupFile(StringRef Filename, + const FileEntry *LookupFile(SourceLocation FilenameLoc, StringRef Filename, bool isAngled, const DirectoryLookup *FromDir, const DirectoryLookup *&CurDir, SmallVectorImpl<char> *SearchPath, SmallVectorImpl<char> *RelativePath, - Module **SuggestedModule, + ModuleMap::KnownHeader *SuggestedModule, bool SkipCache = false); /// GetCurLookup - The DirectoryLookup structure used to find the current @@ -1273,6 +1283,8 @@ private: IncludeMacroStack.pop_back(); } + void PropagateLineStartLeadingSpaceInfo(Token &Result); + /// \brief Allocate a new MacroInfo object. MacroInfo *AllocateMacroInfo(); @@ -1329,7 +1341,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. + /// we lexed a token, return true; otherwise the caller should lex again. bool HandleMacroExpandedIdentifier(Token &Tok, MacroDirective *MD); /// \brief Cache macro expanded tokens for TokenLexers. @@ -1400,7 +1412,7 @@ private: bool InCachingLexMode() const { // If the Lexer pointers are 0 and IncludeMacroStack is empty, it means // that we are past EOF, not that we are in CachingLex mode. - return CurPPLexer == 0 && CurTokenLexer == 0 && CurPTHLexer == 0 && + return !CurPPLexer && !CurTokenLexer && !CurPTHLexer && !IncludeMacroStack.empty(); } void EnterCachingLexMode(); @@ -1432,8 +1444,32 @@ private: void HandleImportDirective(SourceLocation HashLoc, Token &Tok); void HandleMicrosoftImportDirective(Token &Tok); + // Module inclusion testing. + /// \brief Find the module for the source or header file that \p FilenameLoc + /// points to. + Module *getModuleForLocation(SourceLocation FilenameLoc); + + /// \brief Verify that a private header is included only from within its + /// module. + bool violatesPrivateInclude(Module *RequestingModule, + const FileEntry *IncFileEnt, + ModuleMap::ModuleHeaderRole Role, + Module *RequestedModule); + + /// \brief Verify that a module includes headers only from modules that it + /// has declared that it uses. + bool violatesUseDeclarations(Module *RequestingModule, + Module *RequestedModule); + + /// \brief Verify that it is legal for the source file that \p FilenameLoc + /// points to to include the file \p Filename. + /// + /// Tries to reuse \p IncFileEnt. + void verifyModuleInclude(SourceLocation FilenameLoc, StringRef Filename, + const FileEntry *IncFileEnt); + // Macro handling. - void HandleDefineDirective(Token &Tok); + void HandleDefineDirective(Token &Tok, bool ImmediatelyAfterTopLevelIfndef); void HandleUndefDirective(Token &Tok); // Conditional Inclusion. @@ -1445,7 +1481,8 @@ private: void HandleElifDirective(Token &Tok); // Pragmas. - void HandlePragmaDirective(unsigned Introducer); + void HandlePragmaDirective(SourceLocation IntroducerLoc, + PragmaIntroducerKind Introducer); public: void HandlePragmaOnce(Token &OnceTok); void HandlePragmaMark(); diff --git a/include/clang/Lex/PreprocessorLexer.h b/include/clang/Lex/PreprocessorLexer.h index 20fb8a0..27a8df4 100644 --- a/include/clang/Lex/PreprocessorLexer.h +++ b/include/clang/Lex/PreprocessorLexer.h @@ -111,9 +111,9 @@ protected: /// stack, returning information about it. If the conditional stack is empty, /// this returns true and does not fill in the arguments. bool popConditionalLevel(PPConditionalInfo &CI) { - if (ConditionalStack.empty()) return true; - CI = ConditionalStack.back(); - ConditionalStack.pop_back(); + if (ConditionalStack.empty()) + return true; + CI = ConditionalStack.pop_back_val(); return false; } diff --git a/include/clang/Lex/Token.h b/include/clang/Lex/Token.h index bcbe9c9..4f6391d 100644 --- a/include/clang/Lex/Token.h +++ b/include/clang/Lex/Token.h @@ -71,13 +71,16 @@ public: // Various flags set per token: enum TokenFlags { - StartOfLine = 0x01, // At start of line or only after whitespace. - LeadingSpace = 0x02, // Whitespace exists before this token. + StartOfLine = 0x01, // At start of line or only after whitespace + // (considering the line after macro expansion). + LeadingSpace = 0x02, // Whitespace exists before this token (considering + // whitespace after macro expansion). DisableExpand = 0x04, // This identifier may never be macro expanded. NeedsCleaning = 0x08, // Contained an escaped newline or trigraph. LeadingEmptyMacro = 0x10, // Empty macro exists before this token. HasUDSuffix = 0x20, // This string or character literal has a ud-suffix. - HasUCN = 0x40 // This identifier contains a UCN. + HasUCN = 0x40, // This identifier contains a UCN. + IgnoredComma = 0x80 // This comma is not a macro argument separator (MS). }; tok::TokenKind getKind() const { return (tok::TokenKind)Kind; } diff --git a/include/clang/Lex/TokenLexer.h b/include/clang/Lex/TokenLexer.h index 090402a..7c8cfd0 100644 --- a/include/clang/Lex/TokenLexer.h +++ b/include/clang/Lex/TokenLexer.h @@ -136,7 +136,7 @@ public: unsigned isNextTokenLParen() const; /// Lex - Lex and return a token from this macro stream. - void Lex(Token &Tok); + bool Lex(Token &Tok); /// isParsingPreprocessorDirective - Return true if we are in the middle of a /// preprocessor directive. @@ -181,6 +181,8 @@ private: /// macro definition. void updateLocForMacroArgTokens(SourceLocation ArgIdSpellLoc, Token *begin_tokens, Token *end_tokens); + + void PropagateLineStartLeadingSpaceInfo(Token &Result); }; } // end namespace clang |