diff options
Diffstat (limited to 'contrib/llvm/tools/clang/lib/Lex/PPMacroExpansion.cpp')
-rw-r--r-- | contrib/llvm/tools/clang/lib/Lex/PPMacroExpansion.cpp | 134 |
1 files changed, 92 insertions, 42 deletions
diff --git a/contrib/llvm/tools/clang/lib/Lex/PPMacroExpansion.cpp b/contrib/llvm/tools/clang/lib/Lex/PPMacroExpansion.cpp index e10c95c..fe70585 100644 --- a/contrib/llvm/tools/clang/lib/Lex/PPMacroExpansion.cpp +++ b/contrib/llvm/tools/clang/lib/Lex/PPMacroExpansion.cpp @@ -24,7 +24,7 @@ #include "clang/Lex/LiteralSupport.h" #include "llvm/ADT/StringSwitch.h" #include "llvm/ADT/STLExtras.h" -#include "llvm/Config/config.h" +#include "llvm/Config/llvm-config.h" #include "llvm/Support/raw_ostream.h" #include "llvm/Support/ErrorHandling.h" #include <cstdio> @@ -47,13 +47,18 @@ MacroInfo *Preprocessor::getInfoForMacro(IdentifierInfo *II) const { /// setMacroInfo - Specify a macro for this identifier. /// -void Preprocessor::setMacroInfo(IdentifierInfo *II, MacroInfo *MI) { +void Preprocessor::setMacroInfo(IdentifierInfo *II, MacroInfo *MI, + bool LoadedFromAST) { if (MI) { Macros[II] = MI; II->setHasMacroDefinition(true); + if (II->isFromAST() && !LoadedFromAST) + II->setChangedSinceDeserialization(); } else if (II->hasMacroDefinition()) { Macros.erase(II); II->setHasMacroDefinition(false); + if (II->isFromAST() && !LoadedFromAST) + II->setChangedSinceDeserialization(); } } @@ -96,7 +101,7 @@ void Preprocessor::RegisterBuiltinMacros() { Ident__has_warning = RegisterBuiltinMacro(*this, "__has_warning"); // Microsoft Extensions. - if (Features.MicrosoftExt) + if (LangOpts.MicrosoftExt) Ident__pragma = RegisterBuiltinMacro(*this, "__pragma"); else Ident__pragma = 0; @@ -112,6 +117,11 @@ static bool isTrivialSingleTokenExpansion(const MacroInfo *MI, // If the token isn't an identifier, it's always literally expanded. if (II == 0) return true; + // If the information about this identifier is out of date, update it from + // the external source. + if (II->isOutOfDate()) + PP.getExternalSource()->updateOutOfDateIdentifier(*II); + // If the identifier is a macro, and if that macro is enabled, it may be // expanded so it's not a trivial expansion. if (II->hasMacroDefinition() && PP.getMacroInfo(II)->isEnabled() && @@ -296,8 +306,10 @@ bool Preprocessor::HandleMacroExpandedIdentifier(Token &Identifier, // unexpandable. if (IdentifierInfo *NewII = Identifier.getIdentifierInfo()) { if (MacroInfo *NewMI = getMacroInfo(NewII)) - if (!NewMI->isEnabled() || NewMI == MI) + if (!NewMI->isEnabled() || NewMI == MI) { Identifier.setFlag(Token::DisableExpand); + Diag(Identifier, diag::pp_disabled_macro_expansion); + } } // Since this is not an identifier token, it can't be macro expanded, so @@ -421,8 +433,8 @@ MacroArgs *Preprocessor::ReadFunctionLikeMacroArgs(Token &MacroName, // Empty arguments are standard in C99 and C++0x, and are supported as an extension in // other modes. - if (ArgTokens.size() == ArgTokenStart && !Features.C99) - Diag(Tok, Features.CPlusPlus0x ? + if (ArgTokens.size() == ArgTokenStart && !LangOpts.C99) + Diag(Tok, LangOpts.CPlusPlus0x ? diag::warn_cxx98_compat_empty_fnmacro_arg : diag::ext_empty_fnmacro_arg); @@ -576,9 +588,15 @@ 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, const IdentifierInfo *II) { - const LangOptions &LangOpts = PP.getLangOptions(); + const LangOptions &LangOpts = PP.getLangOpts(); + StringRef Feature = II->getName(); - return llvm::StringSwitch<bool>(II->getName()) + // Normalize the feature name, __foo__ becomes foo. + if (Feature.startswith("__") && Feature.endswith("__") && Feature.size() >= 4) + Feature = Feature.substr(2, Feature.size() - 4); + + return llvm::StringSwitch<bool>(Feature) + .Case("address_sanitizer", LangOpts.AddressSanitizer) .Case("attribute_analyzer_noreturn", true) .Case("attribute_availability", true) .Case("attribute_cf_returns_not_retained", true) @@ -603,48 +621,60 @@ static bool HasFeature(const Preprocessor &PP, const IdentifierInfo *II) { .Case("objc_arc", LangOpts.ObjCAutoRefCount) .Case("objc_arc_weak", LangOpts.ObjCAutoRefCount && LangOpts.ObjCRuntimeHasWeak) + .Case("objc_default_synthesize_properties", LangOpts.ObjC2) .Case("objc_fixed_enum", LangOpts.ObjC2) .Case("objc_instancetype", LangOpts.ObjC2) + .Case("objc_modules", LangOpts.ObjC2 && LangOpts.Modules) .Case("objc_nonfragile_abi", LangOpts.ObjCNonFragileABI) .Case("objc_weak_class", LangOpts.ObjCNonFragileABI) .Case("ownership_holds", true) .Case("ownership_returns", true) .Case("ownership_takes", true) - // C1X features - .Case("c_alignas", LangOpts.C1X) - .Case("c_generic_selections", LangOpts.C1X) - .Case("c_static_assert", LangOpts.C1X) - // C++0x features + .Case("objc_bool", true) + .Case("objc_subscripting", LangOpts.ObjCNonFragileABI) + .Case("objc_array_literals", LangOpts.ObjC2) + .Case("objc_dictionary_literals", LangOpts.ObjC2) + .Case("arc_cf_code_audited", true) + // C11 features + .Case("c_alignas", LangOpts.C11) + .Case("c_atomic", LangOpts.C11) + .Case("c_generic_selections", LangOpts.C11) + .Case("c_static_assert", LangOpts.C11) + // C++11 features .Case("cxx_access_control_sfinae", LangOpts.CPlusPlus0x) .Case("cxx_alias_templates", LangOpts.CPlusPlus0x) .Case("cxx_alignas", LangOpts.CPlusPlus0x) + .Case("cxx_atomic", LangOpts.CPlusPlus0x) .Case("cxx_attributes", LangOpts.CPlusPlus0x) .Case("cxx_auto_type", LangOpts.CPlusPlus0x) - //.Case("cxx_constexpr", false); + .Case("cxx_constexpr", LangOpts.CPlusPlus0x) .Case("cxx_decltype", LangOpts.CPlusPlus0x) + .Case("cxx_decltype_incomplete_return_types", LangOpts.CPlusPlus0x) .Case("cxx_default_function_template_args", LangOpts.CPlusPlus0x) + .Case("cxx_defaulted_functions", LangOpts.CPlusPlus0x) .Case("cxx_delegating_constructors", LangOpts.CPlusPlus0x) .Case("cxx_deleted_functions", LangOpts.CPlusPlus0x) .Case("cxx_explicit_conversions", LangOpts.CPlusPlus0x) - //.Case("cxx_generalized_initializers", LangOpts.CPlusPlus0x) + .Case("cxx_generalized_initializers", LangOpts.CPlusPlus0x) .Case("cxx_implicit_moves", LangOpts.CPlusPlus0x) //.Case("cxx_inheriting_constructors", false) .Case("cxx_inline_namespaces", LangOpts.CPlusPlus0x) - //.Case("cxx_lambdas", false) + .Case("cxx_lambdas", LangOpts.CPlusPlus0x) + .Case("cxx_local_type_template_args", LangOpts.CPlusPlus0x) .Case("cxx_nonstatic_member_init", LangOpts.CPlusPlus0x) .Case("cxx_noexcept", LangOpts.CPlusPlus0x) .Case("cxx_nullptr", LangOpts.CPlusPlus0x) .Case("cxx_override_control", LangOpts.CPlusPlus0x) .Case("cxx_range_for", LangOpts.CPlusPlus0x) - //.Case("cxx_raw_string_literals", false) + .Case("cxx_raw_string_literals", LangOpts.CPlusPlus0x) .Case("cxx_reference_qualified_functions", LangOpts.CPlusPlus0x) .Case("cxx_rvalue_references", LangOpts.CPlusPlus0x) .Case("cxx_strong_enums", LangOpts.CPlusPlus0x) .Case("cxx_static_assert", LangOpts.CPlusPlus0x) .Case("cxx_trailing_return", LangOpts.CPlusPlus0x) - //.Case("cxx_unicode_literals", false) - //.Case("cxx_unrestricted_unions", false) - //.Case("cxx_user_literals", false) + .Case("cxx_unicode_literals", LangOpts.CPlusPlus0x) + .Case("cxx_unrestricted_unions", LangOpts.CPlusPlus0x) + .Case("cxx_user_literals", LangOpts.CPlusPlus0x) .Case("cxx_variadic_templates", LangOpts.CPlusPlus0x) // Type traits .Case("has_nothrow_assign", LangOpts.CPlusPlus) @@ -668,6 +698,7 @@ static bool HasFeature(const Preprocessor &PP, const IdentifierInfo *II) { PP.getIdentifierInfo("__is_empty")->getTokenID() != tok::identifier) .Case("is_enum", LangOpts.CPlusPlus) + .Case("is_final", LangOpts.CPlusPlus) .Case("is_literal", LangOpts.CPlusPlus) .Case("is_standard_layout", LangOpts.CPlusPlus) // __is_pod is available only if the horrible @@ -680,8 +711,11 @@ static bool HasFeature(const Preprocessor &PP, const IdentifierInfo *II) { != tok::identifier) .Case("is_polymorphic", LangOpts.CPlusPlus) .Case("is_trivial", LangOpts.CPlusPlus) + .Case("is_trivially_assignable", LangOpts.CPlusPlus) + .Case("is_trivially_constructible", LangOpts.CPlusPlus) .Case("is_trivially_copyable", LangOpts.CPlusPlus) .Case("is_union", LangOpts.CPlusPlus) + .Case("modules", LangOpts.Modules) .Case("tls", PP.getTargetInfo().isTLSSupported()) .Case("underlying_type", LangOpts.CPlusPlus) .Default(false); @@ -700,19 +734,28 @@ static bool HasExtension(const Preprocessor &PP, const IdentifierInfo *II) { DiagnosticsEngine::Ext_Error) return false; - const LangOptions &LangOpts = PP.getLangOptions(); + const LangOptions &LangOpts = PP.getLangOpts(); + StringRef Extension = II->getName(); + + // Normalize the extension name, __foo__ becomes foo. + if (Extension.startswith("__") && Extension.endswith("__") && + Extension.size() >= 4) + Extension = Extension.substr(2, Extension.size() - 4); // Because we inherit the feature list from HasFeature, this string switch // must be less restrictive than HasFeature's. - return llvm::StringSwitch<bool>(II->getName()) - // C1X features supported by other languages as extensions. + return llvm::StringSwitch<bool>(Extension) + // C11 features supported by other languages as extensions. .Case("c_alignas", true) + .Case("c_atomic", true) .Case("c_generic_selections", true) .Case("c_static_assert", true) // C++0x features supported by other languages as extensions. + .Case("cxx_atomic", LangOpts.CPlusPlus) .Case("cxx_deleted_functions", LangOpts.CPlusPlus) .Case("cxx_explicit_conversions", LangOpts.CPlusPlus) .Case("cxx_inline_namespaces", LangOpts.CPlusPlus) + .Case("cxx_local_type_template_args", LangOpts.CPlusPlus) .Case("cxx_nonstatic_member_init", LangOpts.CPlusPlus) .Case("cxx_override_control", LangOpts.CPlusPlus) .Case("cxx_range_for", LangOpts.CPlusPlus) @@ -724,7 +767,12 @@ static bool HasExtension(const Preprocessor &PP, const IdentifierInfo *II) { /// HasAttribute - Return true if we recognize and implement the attribute /// specified by the given identifier. static bool HasAttribute(const IdentifierInfo *II) { - return llvm::StringSwitch<bool>(II->getName()) + StringRef Name = II->getName(); + // Normalize the attribute name, __foo__ becomes foo. + if (Name.startswith("__") && Name.endswith("__") && Name.size() >= 4) + Name = Name.substr(2, Name.size() - 4); + + return llvm::StringSwitch<bool>(Name) #include "clang/Lex/AttrSpellings.inc" .Default(false); } @@ -753,7 +801,7 @@ static bool EvaluateHasIncludeCommon(Token &Tok, PP.getCurrentLexer()->LexIncludeFilename(Tok); // Reserve a buffer to get the spelling. - llvm::SmallString<128> FilenameBuffer; + SmallString<128> FilenameBuffer; StringRef Filename; SourceLocation EndLoc; @@ -784,6 +832,16 @@ static bool EvaluateHasIncludeCommon(Token &Tok, return false; } + // Get ')'. + PP.LexNonComment(Tok); + + // Ensure we have a trailing ). + if (Tok.isNot(tok::r_paren)) { + PP.Diag(Tok.getLocation(), diag::err_pp_missing_rparen) << II->getName(); + PP.Diag(LParenLoc, diag::note_matching) << "("; + return false; + } + bool isAngled = PP.GetIncludeFilenameSpelling(Tok.getLocation(), Filename); // If GetIncludeFilenameSpelling set the start ptr to null, there was an // error. @@ -795,20 +853,8 @@ static bool EvaluateHasIncludeCommon(Token &Tok, const FileEntry *File = PP.LookupFile(Filename, isAngled, LookupFrom, CurDir, NULL, NULL, NULL); - // Get the result value. Result = true means the file exists. - bool Result = File != 0; - - // Get ')'. - PP.LexNonComment(Tok); - - // Ensure we have a trailing ). - if (Tok.isNot(tok::r_paren)) { - PP.Diag(Tok.getLocation(), diag::err_pp_missing_rparen) << II->getName(); - PP.Diag(LParenLoc, diag::note_matching) << "("; - return false; - } - - return Result; + // Get the result value. A result of true means the file exists. + return File != 0; } /// EvaluateHasInclude - Process a '__has_include("path")' expression. @@ -855,7 +901,7 @@ void Preprocessor::ExpandBuiltinMacro(Token &Tok) { ++NumBuiltinMacroExpanded; - llvm::SmallString<128> TmpBuffer; + SmallString<128> TmpBuffer; llvm::raw_svector_ostream OS(TmpBuffer); // Set up the return result. @@ -902,7 +948,7 @@ void Preprocessor::ExpandBuiltinMacro(Token &Tok) { } // Escape this filename. Turn '\' -> '\\' '"' -> '\"' - llvm::SmallString<128> FN; + SmallString<128> FN; if (PLoc.isValid()) { FN += PLoc.getFilename(); Lexer::Stringify(FN); @@ -1010,7 +1056,8 @@ void Preprocessor::ExpandBuiltinMacro(Token &Tok) { } OS << (int)Value; - Tok.setKind(tok::numeric_constant); + if (IsValid) + Tok.setKind(tok::numeric_constant); } else if (II == Ident__has_include || II == Ident__has_include_next) { // The argument to these two builtins should be a parenthesized @@ -1049,6 +1096,9 @@ void Preprocessor::ExpandBuiltinMacro(Token &Tok) { // from macro expansion. SmallVector<Token, 4> StrToks; while (Tok.is(tok::string_literal)) { + // Complain about, and drop, any ud-suffix. + if (Tok.hasUDSuffix()) + Diag(Tok, diag::err_invalid_string_udl); StrToks.push_back(Tok); LexUnexpandedToken(Tok); } |