diff options
Diffstat (limited to 'lib/Lex')
-rw-r--r-- | lib/Lex/MacroInfo.cpp | 5 | ||||
-rw-r--r-- | lib/Lex/PPDirectives.cpp | 37 | ||||
-rw-r--r-- | lib/Lex/PPLexerChange.cpp | 23 |
3 files changed, 61 insertions, 4 deletions
diff --git a/lib/Lex/MacroInfo.cpp b/lib/Lex/MacroInfo.cpp index 5a7af56398..3d0c9a1c2b 100644 --- a/lib/Lex/MacroInfo.cpp +++ b/lib/Lex/MacroInfo.cpp @@ -27,7 +27,8 @@ MacroInfo::MacroInfo(SourceLocation DefLoc) : Location(DefLoc) { IsAllowRedefinitionsWithoutWarning = false; IsWarnIfUnused = false; IsDefinitionLengthCached = false; - + IsPublic = true; + ArgumentList = 0; NumArguments = 0; } @@ -48,6 +49,8 @@ MacroInfo::MacroInfo(const MacroInfo &MI, llvm::BumpPtrAllocator &PPAllocator) { IsWarnIfUnused = MI.IsWarnIfUnused; IsDefinitionLengthCached = MI.IsDefinitionLengthCached; DefinitionLength = MI.DefinitionLength; + IsPublic = MI.IsPublic; + ArgumentList = 0; NumArguments = 0; setArgumentList(MI.ArgumentList, MI.NumArguments, PPAllocator); diff --git a/lib/Lex/PPDirectives.cpp b/lib/Lex/PPDirectives.cpp index de50c750e4..9446d51f9d 100644 --- a/lib/Lex/PPDirectives.cpp +++ b/lib/Lex/PPDirectives.cpp @@ -666,6 +666,8 @@ TryAgain: case tok::pp___export_macro__: return HandleMacroExportDirective(Result); + case tok::pp___private_macro__: + return HandleMacroPrivateDirective(Result); } break; } @@ -1035,13 +1037,44 @@ void Preprocessor::HandleMacroExportDirective(Token &Tok) { // If the macro is not defined, this is an error. if (MI == 0) { - Diag(MacroNameTok, diag::err_pp_export_non_macro) + Diag(MacroNameTok, diag::err_pp_visibility_non_macro) << MacroNameTok.getIdentifierInfo(); return; } // Note that this macro has now been exported. - MI->setExportLocation(MacroNameTok.getLocation()); + MI->setVisibility(/*IsPublic=*/true, MacroNameTok.getLocation()); + + // If this macro definition came from a PCH file, mark it + // as having changed since serialization. + if (MI->isFromAST()) + MI->setChangedAfterLoad(); +} + +/// \brief Handle a #__private_macro__ directive. +void Preprocessor::HandleMacroPrivateDirective(Token &Tok) { + Token MacroNameTok; + ReadMacroName(MacroNameTok, 2); + + // Error reading macro name? If so, diagnostic already issued. + if (MacroNameTok.is(tok::eod)) + return; + + // Check to see if this is the last token on the #__private_macro__ line. + CheckEndOfDirective("__private_macro__"); + + // Okay, we finally have a valid identifier to undef. + MacroInfo *MI = getMacroInfo(MacroNameTok.getIdentifierInfo()); + + // If the macro is not defined, this is an error. + if (MI == 0) { + Diag(MacroNameTok, diag::err_pp_visibility_non_macro) + << MacroNameTok.getIdentifierInfo(); + return; + } + + // Note that this macro has now been marked private. + MI->setVisibility(/*IsPublic=*/false, MacroNameTok.getLocation()); // If this macro definition came from a PCH file, mark it // as having changed since serialization. diff --git a/lib/Lex/PPLexerChange.cpp b/lib/Lex/PPLexerChange.cpp index 25a98ae47b..da6c8aa589 100644 --- a/lib/Lex/PPLexerChange.cpp +++ b/lib/Lex/PPLexerChange.cpp @@ -16,6 +16,7 @@ #include "clang/Lex/HeaderSearch.h" #include "clang/Lex/MacroInfo.h" #include "clang/Lex/LexDiagnostic.h" +#include "clang/Basic/FileManager.h" #include "clang/Basic/SourceManager.h" #include "llvm/Support/MemoryBuffer.h" using namespace clang; @@ -211,8 +212,28 @@ bool Preprocessor::HandleEndOfFile(Token &Result, bool isEndOfMacro) { CurPPLexer->MIOpt.GetControllingMacroAtEndOfFile()) { // Okay, this has a controlling macro, remember in HeaderFileInfo. if (const FileEntry *FE = - SourceMgr.getFileEntryForID(CurPPLexer->getFileID())) + SourceMgr.getFileEntryForID(CurPPLexer->getFileID())) { HeaderInfo.SetFileControllingMacro(FE, ControllingMacro); + + // Controlling macros are implicitly private. + if (MacroInfo *MI = getMacroInfo( + const_cast<IdentifierInfo *>(ControllingMacro))) { + if (MI->getVisibilityLocation().isInvalid()) { + // FIXME: HACK! Mark controlling macros from system headers as + // exported, along with our own Clang headers. This is a gross + // hack to deal with the fact that system headers are included in + // many places within module headers, but are not themselves + // modularized. + if ((StringRef(FE->getName()).find("lib/clang") + == StringRef::npos) && + (StringRef(FE->getName()).find("usr/include") + == StringRef::npos) && + (StringRef(FE->getName()).find("usr/local/include") + == StringRef::npos)) + MI->setVisibility(false, SourceLocation()); + } + } + } } } |