diff options
Diffstat (limited to 'lib/Lex/PPMacroExpansion.cpp')
-rw-r--r-- | lib/Lex/PPMacroExpansion.cpp | 95 |
1 files changed, 72 insertions, 23 deletions
diff --git a/lib/Lex/PPMacroExpansion.cpp b/lib/Lex/PPMacroExpansion.cpp index 2ade6df9456a..aebebaac46ac 100644 --- a/lib/Lex/PPMacroExpansion.cpp +++ b/lib/Lex/PPMacroExpansion.cpp @@ -12,25 +12,49 @@ // //===----------------------------------------------------------------------===// -#include "clang/Lex/Preprocessor.h" #include "clang/Basic/Attributes.h" #include "clang/Basic/FileManager.h" -#include "clang/Basic/SourceManager.h" +#include "clang/Basic/IdentifierTable.h" +#include "clang/Basic/LLVM.h" +#include "clang/Basic/LangOptions.h" +#include "clang/Basic/ObjCRuntime.h" +#include "clang/Basic/SourceLocation.h" #include "clang/Basic/TargetInfo.h" #include "clang/Lex/CodeCompletionHandler.h" +#include "clang/Lex/DirectoryLookup.h" #include "clang/Lex/ExternalPreprocessorSource.h" #include "clang/Lex/LexDiagnostic.h" #include "clang/Lex/MacroArgs.h" #include "clang/Lex/MacroInfo.h" -#include "llvm/ADT/STLExtras.h" +#include "clang/Lex/Preprocessor.h" +#include "clang/Lex/PreprocessorLexer.h" +#include "clang/Lex/PTHLexer.h" +#include "clang/Lex/Token.h" +#include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/DenseSet.h" +#include "llvm/ADT/FoldingSet.h" +#include "llvm/ADT/None.h" +#include "llvm/ADT/Optional.h" #include "llvm/ADT/SmallString.h" +#include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/StringRef.h" #include "llvm/ADT/StringSwitch.h" #include "llvm/Config/llvm-config.h" +#include "llvm/Support/Casting.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/Format.h" #include "llvm/Support/raw_ostream.h" -#include <cstdio> +#include <algorithm> +#include <cassert> +#include <cstddef> +#include <cstring> #include <ctime> +#include <string> +#include <tuple> +#include <utility> + using namespace clang; MacroDirective * @@ -68,12 +92,35 @@ void Preprocessor::appendMacroDirective(IdentifierInfo *II, MacroDirective *MD){ } void Preprocessor::setLoadedMacroDirective(IdentifierInfo *II, + MacroDirective *ED, MacroDirective *MD) { + // Normally, when a macro is defined, it goes through appendMacroDirective() + // above, which chains a macro to previous defines, undefs, etc. + // However, in a pch, the whole macro history up to the end of the pch is + // stored, so ASTReader goes through this function instead. + // However, built-in macros are already registered in the Preprocessor + // ctor, and ASTWriter stops writing the macro chain at built-in macros, + // so in that case the chain from the pch needs to be spliced to the existing + // built-in. + assert(II && MD); MacroState &StoredMD = CurSubmoduleState->Macros[II]; - assert(!StoredMD.getLatest() && - "the macro history was modified before initializing it from a pch"); - StoredMD = MD; + + if (auto *OldMD = StoredMD.getLatest()) { + // shouldIgnoreMacro() in ASTWriter also stops at macros from the + // predefines buffer in module builds. However, in module builds, modules + // are loaded completely before predefines are processed, so StoredMD + // will be nullptr for them when they're loaded. StoredMD should only be + // non-nullptr for builtins read from a pch file. + assert(OldMD->getMacroInfo()->isBuiltinMacro() && + "only built-ins should have an entry here"); + assert(!OldMD->getPrevious() && "builtin should only have a single entry"); + ED->setPrevious(OldMD); + StoredMD.setLatest(MD); + } else { + StoredMD = MD; + } + // Setup the identifier as having associated macro history. II->setHasMacroDefinition(true); if (!MD->isDefined() && LeafModuleMacros.find(II) == LeafModuleMacros.end()) @@ -286,7 +333,6 @@ static IdentifierInfo *RegisterBuiltinMacro(Preprocessor &PP, const char *Name){ return Id; } - /// RegisterBuiltinMacros - Register builtin macros, such as __LINE__ with the /// identifier table. void Preprocessor::RegisterBuiltinMacros() { @@ -367,10 +413,8 @@ static bool isTrivialSingleTokenExpansion(const MacroInfo *MI, // If this is a function-like macro invocation, it's safe to trivially expand // as long as the identifier is not a macro argument. return std::find(MI->arg_begin(), MI->arg_end(), II) == MI->arg_end(); - } - /// isNextPPTokenLParen - Determine whether the next preprocessor token to be /// lexed is a '('. If so, consume the token and return true, if not, this /// method should have no observable side-effect on the lexed tokens. @@ -390,8 +434,7 @@ bool Preprocessor::isNextPPTokenLParen() { // macro stack. if (CurPPLexer) return false; - for (unsigned i = IncludeMacroStack.size(); i != 0; --i) { - IncludeStackInfo &Entry = IncludeMacroStack[i-1]; + for (const IncludeStackInfo &Entry : llvm::reverse(IncludeMacroStack)) { if (Entry.TheLexer) Val = Entry.TheLexer->isNextPPTokenLParen(); else if (Entry.ThePTHLexer) @@ -480,8 +523,7 @@ bool Preprocessor::HandleMacroExpandedIdentifier(Token &Identifier, } else { Callbacks->MacroExpands(Identifier, M, ExpansionRange, Args); if (!DelayedMacroExpandsCallbacks.empty()) { - for (unsigned i=0, e = DelayedMacroExpandsCallbacks.size(); i!=e; ++i) { - MacroExpandsInfo &Info = DelayedMacroExpandsCallbacks[i]; + for (const MacroExpandsInfo &Info : DelayedMacroExpandsCallbacks) { // FIXME: We lose macro args info with delayed callback. Callbacks->MacroExpands(Info.Tok, Info.MD, Info.Range, /*Args=*/nullptr); @@ -735,14 +777,14 @@ MacroArgs *Preprocessor::ReadFunctionLikeMacroArgs(Token &MacroName, assert(Tok.isOneOf(tok::l_paren, tok::comma) && "only expect argument separators here"); - unsigned ArgTokenStart = ArgTokens.size(); + size_t ArgTokenStart = ArgTokens.size(); SourceLocation ArgStartLoc = Tok.getLocation(); // C99 6.10.3p11: Keep track of the number of l_parens we have seen. Note // that we already consumed the first one. unsigned NumParens = 0; - while (1) { + while (true) { // Read arguments as unexpanded tokens. This avoids issues, e.g., where // an argument value in a macro could expand to ',' or '(' or ')'. LexUnexpandedToken(Tok); @@ -987,10 +1029,10 @@ Token *Preprocessor::cacheMacroExpandedTokens(TokenLexer *tokLexer, if (cacheNeedsToGrow) { // Go through all the TokenLexers whose 'Tokens' pointer points in the // buffer and update the pointers to the (potential) new buffer array. - for (unsigned i = 0, e = MacroExpandingLexersStack.size(); i != e; ++i) { + for (const auto &Lexer : MacroExpandingLexersStack) { TokenLexer *prevLexer; size_t tokIndex; - std::tie(prevLexer, tokIndex) = MacroExpandingLexersStack[i]; + std::tie(prevLexer, tokIndex) = Lexer; prevLexer->Tokens = MacroExpandedTokens.data() + tokIndex; } } @@ -1043,7 +1085,6 @@ static void ComputeDATE_TIME(SourceLocation &DATELoc, SourceLocation &TIMELoc, } } - /// HasFeature - Return true if we recognize and implement the feature /// specified by the identifier as a standard language feature. static bool HasFeature(const Preprocessor &PP, StringRef Feature) { @@ -1090,6 +1131,7 @@ static bool HasFeature(const Preprocessor &PP, StringRef Feature) { .Case("cxx_rtti", LangOpts.RTTI && LangOpts.RTTIData) .Case("enumerator_attributes", true) .Case("nullability", true) + .Case("nullability_on_arrays", true) .Case("memory_sanitizer", LangOpts.Sanitize.has(SanitizerKind::Memory)) .Case("thread_sanitizer", LangOpts.Sanitize.has(SanitizerKind::Thread)) .Case("dataflow_sanitizer", LangOpts.Sanitize.has(SanitizerKind::DataFlow)) @@ -1171,7 +1213,7 @@ static bool HasFeature(const Preprocessor &PP, StringRef Feature) { .Case("cxx_unrestricted_unions", LangOpts.CPlusPlus11) .Case("cxx_user_literals", LangOpts.CPlusPlus11) .Case("cxx_variadic_templates", LangOpts.CPlusPlus11) - // C++1y features + // C++14 features .Case("cxx_aggregate_nsdmi", LangOpts.CPlusPlus14) .Case("cxx_binary_literals", LangOpts.CPlusPlus14) .Case("cxx_contextual_conversions", LangOpts.CPlusPlus14) @@ -1181,6 +1223,9 @@ static bool HasFeature(const Preprocessor &PP, StringRef Feature) { .Case("cxx_relaxed_constexpr", LangOpts.CPlusPlus14) .Case("cxx_return_type_deduction", LangOpts.CPlusPlus14) .Case("cxx_variable_templates", LangOpts.CPlusPlus14) + // NOTE: For features covered by SD-6, it is preferable to provide *only* + // the SD-6 macro and not a __has_feature check. + // C++ TSes //.Case("cxx_runtime_arrays", LangOpts.CPlusPlusTSArrays) //.Case("cxx_concepts", LangOpts.CPlusPlusTSConcepts) @@ -1264,7 +1309,7 @@ static bool HasExtension(const Preprocessor &PP, StringRef Extension) { .Case("cxx_reference_qualified_functions", LangOpts.CPlusPlus) .Case("cxx_rvalue_references", LangOpts.CPlusPlus) .Case("cxx_variadic_templates", LangOpts.CPlusPlus) - // C++1y features supported by other languages as extensions. + // C++14 features supported by other languages as extensions. .Case("cxx_binary_literals", true) .Case("cxx_init_captures", LangOpts.CPlusPlus11) .Case("cxx_variable_templates", LangOpts.CPlusPlus) @@ -1400,7 +1445,11 @@ static bool EvaluateHasIncludeNext(Token &Tok, // Preprocessor::HandleIncludeNextDirective. const DirectoryLookup *Lookup = PP.GetCurDirLookup(); const FileEntry *LookupFromFile = nullptr; - if (PP.isInPrimaryFile()) { + if (PP.isInPrimaryFile() && PP.getLangOpts().IsHeaderFile) { + // If the main file is a header, then it's either for PCH/AST generation, + // or libclang opened it. Either way, handle it as a normal include below + // and do not complain about __has_include_next. + } else if (PP.isInPrimaryFile()) { Lookup = nullptr; PP.Diag(Tok, diag::pp_include_next_in_primary); } else if (PP.getCurrentSubmodule()) { @@ -1796,7 +1845,7 @@ void Preprocessor::ExpandBuiltinMacro(Token &Tok) { [this](Token &Tok, bool &HasLexedNextToken) -> int { IdentifierInfo *II = ExpectFeatureIdentifierInfo(Tok, *this, diag::err_expected_id_building_module); - return getLangOpts().CompilingModule && II && + return getLangOpts().isCompilingModule() && II && (II->getName() == getLangOpts().CurrentModule); }); } else if (II == Ident__MODULE__) { |