diff options
Diffstat (limited to 'lib/Lex/PPDirectives.cpp')
-rw-r--r-- | lib/Lex/PPDirectives.cpp | 339 |
1 files changed, 241 insertions, 98 deletions
diff --git a/lib/Lex/PPDirectives.cpp b/lib/Lex/PPDirectives.cpp index 1741c302f338..bf0ce72f6668 100644 --- a/lib/Lex/PPDirectives.cpp +++ b/lib/Lex/PPDirectives.cpp @@ -25,7 +25,7 @@ #include "clang/Lex/Pragma.h" #include "llvm/ADT/APInt.h" #include "llvm/Support/ErrorHandling.h" -#include "llvm/Support/FileSystem.h" +#include "llvm/Support/Path.h" #include "llvm/Support/SaveAndRestore.h" using namespace clang; @@ -34,23 +34,10 @@ using namespace clang; //===----------------------------------------------------------------------===// MacroInfo *Preprocessor::AllocateMacroInfo() { - MacroInfoChain *MIChain; - - if (MICache) { - MIChain = MICache; - MICache = MICache->Next; - } - else { - MIChain = BP.Allocate<MacroInfoChain>(); - } - + MacroInfoChain *MIChain = BP.Allocate<MacroInfoChain>(); MIChain->Next = MIChainHead; - MIChain->Prev = nullptr; - if (MIChainHead) - MIChainHead->Prev = MIChain; MIChainHead = MIChain; - - return &(MIChain->MI); + return &MIChain->MI; } MacroInfo *Preprocessor::AllocateMacroInfo(SourceLocation L) { @@ -77,45 +64,30 @@ MacroInfo *Preprocessor::AllocateDeserializedMacroInfo(SourceLocation L, DefMacroDirective * Preprocessor::AllocateDefMacroDirective(MacroInfo *MI, SourceLocation Loc, - bool isImported) { - DefMacroDirective *MD = BP.Allocate<DefMacroDirective>(); - new (MD) DefMacroDirective(MI, Loc, isImported); - return MD; + unsigned ImportedFromModuleID, + ArrayRef<unsigned> Overrides) { + unsigned NumExtra = (ImportedFromModuleID ? 1 : 0) + Overrides.size(); + return new (BP.Allocate(sizeof(DefMacroDirective) + + sizeof(unsigned) * NumExtra, + llvm::alignOf<DefMacroDirective>())) + DefMacroDirective(MI, Loc, ImportedFromModuleID, Overrides); } UndefMacroDirective * -Preprocessor::AllocateUndefMacroDirective(SourceLocation UndefLoc) { - UndefMacroDirective *MD = BP.Allocate<UndefMacroDirective>(); - new (MD) UndefMacroDirective(UndefLoc); - return MD; +Preprocessor::AllocateUndefMacroDirective(SourceLocation UndefLoc, + unsigned ImportedFromModuleID, + ArrayRef<unsigned> Overrides) { + unsigned NumExtra = (ImportedFromModuleID ? 1 : 0) + Overrides.size(); + return new (BP.Allocate(sizeof(UndefMacroDirective) + + sizeof(unsigned) * NumExtra, + llvm::alignOf<UndefMacroDirective>())) + UndefMacroDirective(UndefLoc, ImportedFromModuleID, Overrides); } VisibilityMacroDirective * Preprocessor::AllocateVisibilityMacroDirective(SourceLocation Loc, bool isPublic) { - VisibilityMacroDirective *MD = BP.Allocate<VisibilityMacroDirective>(); - new (MD) VisibilityMacroDirective(Loc, isPublic); - return MD; -} - -/// \brief Release the specified MacroInfo to be reused for allocating -/// new MacroInfo objects. -void Preprocessor::ReleaseMacroInfo(MacroInfo *MI) { - MacroInfoChain *MIChain = (MacroInfoChain *)MI; - if (MacroInfoChain *Prev = MIChain->Prev) { - MacroInfoChain *Next = MIChain->Next; - Prev->Next = Next; - if (Next) - Next->Prev = Prev; - } else { - assert(MIChainHead == MIChain); - MIChainHead = MIChain->Next; - MIChainHead->Prev = nullptr; - } - MIChain->Next = MICache; - MICache = MIChain; - - MI->Destroy(); + return new (BP) VisibilityMacroDirective(Loc, isPublic); } /// \brief Read and discard all tokens remaining on the current line until @@ -128,7 +100,56 @@ void Preprocessor::DiscardUntilEndOfDirective() { } while (Tmp.isNot(tok::eod)); } -bool Preprocessor::CheckMacroName(Token &MacroNameTok, char isDefineUndef) { +/// \brief Enumerates possible cases of #define/#undef a reserved identifier. +enum MacroDiag { + MD_NoWarn, //> Not a reserved identifier + MD_KeywordDef, //> Macro hides keyword, enabled by default + MD_ReservedMacro //> #define of #undef reserved id, disabled by default +}; + +/// \brief Checks if the specified identifier is reserved in the specified +/// language. +/// This function does not check if the identifier is a keyword. +static bool isReservedId(StringRef Text, const LangOptions &Lang) { + // C++ [macro.names], C11 7.1.3: + // All identifiers that begin with an underscore and either an uppercase + // letter or another underscore are always reserved for any use. + if (Text.size() >= 2 && Text[0] == '_' && + (isUppercase(Text[1]) || Text[1] == '_')) + return true; + // C++ [global.names] + // Each name that contains a double underscore ... is reserved to the + // implementation for any use. + if (Lang.CPlusPlus) { + if (Text.find("__") != StringRef::npos) + return true; + } + return false; +} + +static MacroDiag shouldWarnOnMacroDef(Preprocessor &PP, IdentifierInfo *II) { + const LangOptions &Lang = PP.getLangOpts(); + StringRef Text = II->getName(); + if (isReservedId(Text, Lang)) + return MD_ReservedMacro; + if (II->isKeyword(Lang)) + return MD_KeywordDef; + if (Lang.CPlusPlus11 && (Text.equals("override") || Text.equals("final"))) + return MD_KeywordDef; + return MD_NoWarn; +} + +static MacroDiag shouldWarnOnMacroUndef(Preprocessor &PP, IdentifierInfo *II) { + const LangOptions &Lang = PP.getLangOpts(); + StringRef Text = II->getName(); + // Do not warn on keyword undef. It is generally harmless and widely used. + if (isReservedId(Text, Lang)) + return MD_ReservedMacro; + return MD_NoWarn; +} + +bool Preprocessor::CheckMacroName(Token &MacroNameTok, MacroUse isDefineUndef, + bool *ShadowFlag) { // Missing macro name? if (MacroNameTok.is(tok::eod)) return Diag(MacroNameTok, diag::err_pp_missing_macro_name); @@ -156,18 +177,42 @@ bool Preprocessor::CheckMacroName(Token &MacroNameTok, char isDefineUndef) { MacroNameTok.setIdentifierInfo(II); } - if (isDefineUndef && II->getPPKeywordID() == tok::pp_defined) { + if ((isDefineUndef != MU_Other) && II->getPPKeywordID() == tok::pp_defined) { // Error if defining "defined": C99 6.10.8/4, C++ [cpp.predefined]p4. return Diag(MacroNameTok, diag::err_defined_macro_name); } - if (isDefineUndef == 2 && II->hasMacroDefinition() && + if (isDefineUndef == MU_Undef && II->hasMacroDefinition() && getMacroInfo(II)->isBuiltinMacro()) { // Warn if undefining "__LINE__" and other builtins, per C99 6.10.8/4 // and C++ [cpp.predefined]p4], but allow it as an extension. Diag(MacroNameTok, diag::ext_pp_undef_builtin_macro); } + // If defining/undefining reserved identifier or a keyword, we need to issue + // a warning. + SourceLocation MacroNameLoc = MacroNameTok.getLocation(); + if (ShadowFlag) + *ShadowFlag = false; + if (!SourceMgr.isInSystemHeader(MacroNameLoc) && + (strcmp(SourceMgr.getBufferName(MacroNameLoc), "<built-in>") != 0)) { + MacroDiag D = MD_NoWarn; + if (isDefineUndef == MU_Define) { + D = shouldWarnOnMacroDef(*this, II); + } + else if (isDefineUndef == MU_Undef) + D = shouldWarnOnMacroUndef(*this, II); + if (D == MD_KeywordDef) { + // We do not want to warn on some patterns widely used in configuration + // scripts. This requires analyzing next tokens, so do not issue warnings + // now, only inform caller. + if (ShadowFlag) + *ShadowFlag = true; + } + if (D == MD_ReservedMacro) + Diag(MacroNameTok, diag::warn_pp_macro_is_reserved_id); + } + // Okay, we got a good identifier. return false; } @@ -175,22 +220,25 @@ bool Preprocessor::CheckMacroName(Token &MacroNameTok, char isDefineUndef) { /// \brief Lex and validate a macro name, which occurs after a /// \#define or \#undef. /// -/// This sets the token kind to eod and discards the rest -/// of the macro line if the macro name is invalid. \p isDefineUndef is 1 if -/// this is due to a a \#define, 2 if \#undef directive, 0 if it is something -/// else (e.g. \#ifdef). -void Preprocessor::ReadMacroName(Token &MacroNameTok, char isDefineUndef) { +/// This sets the token kind to eod and discards the rest of the macro line if +/// the macro name is invalid. +/// +/// \param MacroNameTok Token that is expected to be a macro name. +/// \param isDefineUndef Context in which macro is used. +/// \param ShadowFlag Points to a flag that is set if macro shadows a keyword. +void Preprocessor::ReadMacroName(Token &MacroNameTok, MacroUse isDefineUndef, + bool *ShadowFlag) { // Read the token, don't allow macro expansion on it. LexUnexpandedToken(MacroNameTok); if (MacroNameTok.is(tok::code_completion)) { if (CodeComplete) - CodeComplete->CodeCompleteMacroName(isDefineUndef == 1); + CodeComplete->CodeCompleteMacroName(isDefineUndef == MU_Define); setCodeCompletionReached(); LexUnexpandedToken(MacroNameTok); } - if (!CheckMacroName(MacroNameTok, isDefineUndef)) + if (!CheckMacroName(MacroNameTok, isDefineUndef, ShadowFlag)) return; // Invalid macro name, read and discard the rest of the line and set the @@ -562,6 +610,7 @@ const FileEntry *Preprocessor::LookupFile( StringRef Filename, bool isAngled, const DirectoryLookup *FromDir, + const FileEntry *FromFile, const DirectoryLookup *&CurDir, SmallVectorImpl<char> *SearchPath, SmallVectorImpl<char> *RelativePath, @@ -569,22 +618,33 @@ const FileEntry *Preprocessor::LookupFile( bool SkipCache) { // If the header lookup mechanism may be relative to the current inclusion // stack, record the parent #includes. - SmallVector<const FileEntry *, 16> Includers; - if (!FromDir) { + SmallVector<std::pair<const FileEntry *, const DirectoryEntry *>, 16> + Includers; + if (!FromDir && !FromFile) { FileID FID = getCurrentFileLexer()->getFileID(); const FileEntry *FileEnt = SourceMgr.getFileEntryForID(FID); // If there is no file entry associated with this file, it must be the - // predefines buffer. Any other file is not lexed with a normal lexer, so - // it won't be scanned for preprocessor directives. If we have the - // predefines buffer, resolve #include references (which come from the - // -include command line argument) as if they came from the main file, this - // affects file lookup etc. - if (!FileEnt) - FileEnt = SourceMgr.getFileEntryForID(SourceMgr.getMainFileID()); - - if (FileEnt) - Includers.push_back(FileEnt); + // predefines buffer or the module includes buffer. Any other file is not + // lexed with a normal lexer, so it won't be scanned for preprocessor + // directives. + // + // If we have the predefines buffer, resolve #include references (which come + // from the -include command line argument) from the current working + // directory instead of relative to the main file. + // + // If we have the module includes buffer, resolve #include references (which + // come from header declarations in the module map) relative to the module + // map file. + if (!FileEnt) { + if (FID == SourceMgr.getMainFileID() && MainFileDir) + Includers.push_back(std::make_pair(nullptr, MainFileDir)); + else if ((FileEnt = + SourceMgr.getFileEntryForID(SourceMgr.getMainFileID()))) + Includers.push_back(std::make_pair(FileEnt, FileMgr.getDirectory("."))); + } else { + Includers.push_back(std::make_pair(FileEnt, FileEnt->getDir())); + } // MSVC searches the current include stack from top to bottom for // headers included by quoted include directives. @@ -595,13 +655,35 @@ const FileEntry *Preprocessor::LookupFile( if (IsFileLexer(ISEntry)) if ((FileEnt = SourceMgr.getFileEntryForID( ISEntry.ThePPLexer->getFileID()))) - Includers.push_back(FileEnt); + Includers.push_back(std::make_pair(FileEnt, FileEnt->getDir())); } } } - // Do a standard file entry lookup. CurDir = CurDirLookup; + + if (FromFile) { + // We're supposed to start looking from after a particular file. Search + // the include path until we find that file or run out of files. + const DirectoryLookup *TmpCurDir = CurDir; + const DirectoryLookup *TmpFromDir = nullptr; + while (const FileEntry *FE = HeaderInfo.LookupFile( + Filename, FilenameLoc, isAngled, TmpFromDir, TmpCurDir, + Includers, SearchPath, RelativePath, SuggestedModule, + SkipCache)) { + // Keep looking as if this file did a #include_next. + TmpFromDir = TmpCurDir; + ++TmpFromDir; + if (FE == FromFile) { + // Found it. + FromDir = TmpFromDir; + CurDir = TmpCurDir; + break; + } + } + } + + // Do a standard file entry lookup. const FileEntry *FE = HeaderInfo.LookupFile( Filename, FilenameLoc, isAngled, FromDir, CurDir, Includers, SearchPath, RelativePath, SuggestedModule, SkipCache); @@ -716,7 +798,8 @@ void Preprocessor::HandleDirective(Token &Result) { case tok::pp_import: case tok::pp_include_next: case tok::pp___include_macros: - Diag(Result, diag::err_embedded_include) << II->getName(); + case tok::pp_pragma: + Diag(Result, diag::err_embedded_directive) << II->getName(); DiscardUntilEndOfDirective(); return; default: @@ -1196,7 +1279,7 @@ void Preprocessor::HandleIdentSCCSDirective(Token &Tok) { /// \brief Handle a #public directive. void Preprocessor::HandleMacroPublicDirective(Token &Tok) { Token MacroNameTok; - ReadMacroName(MacroNameTok, 2); + ReadMacroName(MacroNameTok, MU_Undef); // Error reading macro name? If so, diagnostic already issued. if (MacroNameTok.is(tok::eod)) @@ -1223,7 +1306,7 @@ void Preprocessor::HandleMacroPublicDirective(Token &Tok) { /// \brief Handle a #private directive. void Preprocessor::HandleMacroPrivateDirective(Token &Tok) { Token MacroNameTok; - ReadMacroName(MacroNameTok, 2); + ReadMacroName(MacroNameTok, MU_Undef); // Error reading macro name? If so, diagnostic already issued. if (MacroNameTok.is(tok::eod)) @@ -1378,6 +1461,7 @@ static void EnterAnnotationToken(Preprocessor &PP, void Preprocessor::HandleIncludeDirective(SourceLocation HashLoc, Token &IncludeTok, const DirectoryLookup *LookupFrom, + const FileEntry *LookupFromFile, bool isImport) { Token FilenameTok; @@ -1469,12 +1553,14 @@ void Preprocessor::HandleIncludeDirective(SourceLocation HashLoc, SmallString<128> NormalizedPath; if (LangOpts.MSVCCompat) { NormalizedPath = Filename.str(); - llvm::sys::fs::normalize_separators(NormalizedPath); +#ifndef LLVM_ON_WIN32 + llvm::sys::path::native(NormalizedPath); +#endif } const FileEntry *File = LookupFile( FilenameLoc, LangOpts.MSVCCompat ? NormalizedPath.c_str() : Filename, - isAngled, LookupFrom, CurDir, Callbacks ? &SearchPath : nullptr, - Callbacks ? &RelativePath : nullptr, + isAngled, LookupFrom, LookupFromFile, CurDir, + Callbacks ? &SearchPath : nullptr, Callbacks ? &RelativePath : nullptr, HeaderInfo.getHeaderSearchOpts().ModuleMaps ? &SuggestedModule : nullptr); if (Callbacks) { @@ -1488,14 +1574,13 @@ void Preprocessor::HandleIncludeDirective(SourceLocation HashLoc, HeaderInfo.AddSearchPath(DL, isAngled); // Try the lookup again, skipping the cache. - File = LookupFile(FilenameLoc, - LangOpts.MSVCCompat ? NormalizedPath.c_str() - : Filename, - isAngled, LookupFrom, CurDir, nullptr, nullptr, - HeaderInfo.getHeaderSearchOpts().ModuleMaps - ? &SuggestedModule - : nullptr, - /*SkipCache*/ true); + File = LookupFile( + FilenameLoc, + LangOpts.MSVCCompat ? NormalizedPath.c_str() : Filename, isAngled, + LookupFrom, LookupFromFile, CurDir, nullptr, nullptr, + HeaderInfo.getHeaderSearchOpts().ModuleMaps ? &SuggestedModule + : nullptr, + /*SkipCache*/ true); } } } @@ -1517,8 +1602,10 @@ void Preprocessor::HandleIncludeDirective(SourceLocation HashLoc, // provide the user with a possible fixit. if (isAngled) { File = LookupFile( - FilenameLoc, LangOpts.MSVCCompat ? NormalizedPath.c_str() : Filename, - false, LookupFrom, CurDir, Callbacks ? &SearchPath : nullptr, + FilenameLoc, + LangOpts.MSVCCompat ? NormalizedPath.c_str() : Filename, false, + LookupFrom, LookupFromFile, CurDir, + Callbacks ? &SearchPath : nullptr, Callbacks ? &RelativePath : nullptr, HeaderInfo.getHeaderSearchOpts().ModuleMaps ? &SuggestedModule : nullptr); @@ -1539,7 +1626,9 @@ void Preprocessor::HandleIncludeDirective(SourceLocation HashLoc, // If we are supposed to import a module rather than including the header, // do so now. - if (SuggestedModule && getLangOpts().Modules) { + if (SuggestedModule && getLangOpts().Modules && + SuggestedModule.getModule()->getTopLevelModuleName() != + getLangOpts().ImplementationOfModule) { // Compute the module access path corresponding to this module. // FIXME: Should we have a second loadModule() overload to avoid this // extra lookup step? @@ -1713,9 +1802,16 @@ void Preprocessor::HandleIncludeNextDirective(SourceLocation HashLoc, // the current found directory. If we can't do this, issue a // diagnostic. const DirectoryLookup *Lookup = CurDirLookup; + const FileEntry *LookupFromFile = nullptr; if (isInPrimaryFile()) { Lookup = nullptr; Diag(IncludeNextTok, diag::pp_include_next_in_primary); + } else if (CurSubmodule) { + // Start looking up in the directory *after* the one in which the current + // file would be found, if any. + assert(CurPPLexer && "#include_next directive in macro?"); + LookupFromFile = CurPPLexer->getFileEntry(); + Lookup = nullptr; } else if (!Lookup) { Diag(IncludeNextTok, diag::pp_include_next_absolute_path); } else { @@ -1723,7 +1819,8 @@ void Preprocessor::HandleIncludeNextDirective(SourceLocation HashLoc, ++Lookup; } - return HandleIncludeDirective(HashLoc, IncludeNextTok, Lookup); + return HandleIncludeDirective(HashLoc, IncludeNextTok, Lookup, + LookupFromFile); } /// HandleMicrosoftImportDirective - Implements \#import for Microsoft Mode @@ -1749,7 +1846,7 @@ void Preprocessor::HandleImportDirective(SourceLocation HashLoc, return HandleMicrosoftImportDirective(ImportTok); Diag(ImportTok, diag::ext_pp_import_directive); } - return HandleIncludeDirective(HashLoc, ImportTok, nullptr, true); + return HandleIncludeDirective(HashLoc, ImportTok, nullptr, nullptr, true); } /// HandleIncludeMacrosDirective - The -imacros command line option turns into a @@ -1770,7 +1867,7 @@ void Preprocessor::HandleIncludeMacrosDirective(SourceLocation HashLoc, // Treat this as a normal #include for checking purposes. If this is // successful, it will push a new lexer onto the include stack. - HandleIncludeDirective(HashLoc, IncludeMacrosTok, nullptr, false); + HandleIncludeDirective(HashLoc, IncludeMacrosTok); Token TmpTok; do { @@ -1878,6 +1975,52 @@ bool Preprocessor::ReadMacroDefinitionArgList(MacroInfo *MI, Token &Tok) { } } +static bool isConfigurationPattern(Token &MacroName, MacroInfo *MI, + const LangOptions &LOptions) { + if (MI->getNumTokens() == 1) { + const Token &Value = MI->getReplacementToken(0); + + // Macro that is identity, like '#define inline inline' is a valid pattern. + if (MacroName.getKind() == Value.getKind()) + return true; + + // Macro that maps a keyword to the same keyword decorated with leading/ + // trailing underscores is a valid pattern: + // #define inline __inline + // #define inline __inline__ + // #define inline _inline (in MS compatibility mode) + StringRef MacroText = MacroName.getIdentifierInfo()->getName(); + if (IdentifierInfo *II = Value.getIdentifierInfo()) { + if (!II->isKeyword(LOptions)) + return false; + StringRef ValueText = II->getName(); + StringRef TrimmedValue = ValueText; + if (!ValueText.startswith("__")) { + if (ValueText.startswith("_")) + TrimmedValue = TrimmedValue.drop_front(1); + else + return false; + } else { + TrimmedValue = TrimmedValue.drop_front(2); + if (TrimmedValue.endswith("__")) + TrimmedValue = TrimmedValue.drop_back(2); + } + return TrimmedValue.equals(MacroText); + } else { + return false; + } + } + + // #define inline + if ((MacroName.is(tok::kw_extern) || MacroName.is(tok::kw_inline) || + MacroName.is(tok::kw_static) || MacroName.is(tok::kw_const)) && + MI->getNumTokens() == 0) { + return true; + } + + return false; +} + /// HandleDefineDirective - Implements \#define. This consumes the entire macro /// line then lets the caller lex the next real token. void Preprocessor::HandleDefineDirective(Token &DefineTok, @@ -1885,7 +2028,8 @@ void Preprocessor::HandleDefineDirective(Token &DefineTok, ++NumDefined; Token MacroNameTok; - ReadMacroName(MacroNameTok, 1); + bool MacroShadowsKeyword; + ReadMacroName(MacroNameTok, MU_Define, &MacroShadowsKeyword); // Error reading macro name? If so, diagnostic already issued. if (MacroNameTok.is(tok::eod)) @@ -1921,8 +2065,6 @@ void Preprocessor::HandleDefineDirective(Token &DefineTok, // This is a function-like macro definition. Read the argument list. MI->setIsFunctionLike(); if (ReadMacroDefinitionArgList(MI, LastTok)) { - // Forget about MI. - ReleaseMacroInfo(MI); // Throw away the rest of the line. if (CurPPLexer->ParsingPreprocessorDirective) DiscardUntilEndOfDirective(); @@ -2047,7 +2189,6 @@ void Preprocessor::HandleDefineDirective(Token &DefineTok, continue; } else { Diag(Tok, diag::err_pp_stringize_not_parameter); - ReleaseMacroInfo(MI); // Disable __VA_ARGS__ again. Ident__VA_ARGS__->setIsPoisoned(true); @@ -2065,6 +2206,10 @@ void Preprocessor::HandleDefineDirective(Token &DefineTok, } } + if (MacroShadowsKeyword && + !isConfigurationPattern(MacroNameTok, MI, getLangOpts())) { + Diag(MacroNameTok, diag::warn_pp_macro_hides_keyword); + } // Disable __VA_ARGS__ again. Ident__VA_ARGS__->setIsPoisoned(true); @@ -2075,12 +2220,10 @@ void Preprocessor::HandleDefineDirective(Token &DefineTok, if (NumTokens != 0) { if (MI->getReplacementToken(0).is(tok::hashhash)) { Diag(MI->getReplacementToken(0), diag::err_paste_at_start); - ReleaseMacroInfo(MI); return; } if (MI->getReplacementToken(NumTokens-1).is(tok::hashhash)) { Diag(MI->getReplacementToken(NumTokens-1), diag::err_paste_at_end); - ReleaseMacroInfo(MI); return; } } @@ -2138,7 +2281,7 @@ void Preprocessor::HandleUndefDirective(Token &UndefTok) { ++NumUndefined; Token MacroNameTok; - ReadMacroName(MacroNameTok, 2); + ReadMacroName(MacroNameTok, MU_Undef); // Error reading macro name? If so, diagnostic already issued. if (MacroNameTok.is(tok::eod)) |