diff options
Diffstat (limited to 'lib/Lex/Pragma.cpp')
| -rw-r--r-- | lib/Lex/Pragma.cpp | 67 | 
1 files changed, 44 insertions, 23 deletions
| diff --git a/lib/Lex/Pragma.cpp b/lib/Lex/Pragma.cpp index 8ed832893771..26ed674f65aa 100644 --- a/lib/Lex/Pragma.cpp +++ b/lib/Lex/Pragma.cpp @@ -22,6 +22,7 @@  #include "clang/Lex/Preprocessor.h"  #include "llvm/ADT/STLExtras.h"  #include "llvm/ADT/StringSwitch.h" +#include "llvm/ADT/StringExtras.h"  #include "llvm/Support/CrashRecoveryContext.h"  #include "llvm/Support/ErrorHandling.h"  #include <algorithm> @@ -400,7 +401,7 @@ void Preprocessor::HandlePragmaPoison(Token &PoisonTok) {      if (II->isPoisoned()) continue;      // If this is a macro identifier, emit a warning. -    if (II->hasMacroDefinition()) +    if (isMacroDefined(II))        Diag(Tok, diag::pp_poisoning_existing_macro);      // Finally, poison it! @@ -590,8 +591,7 @@ void Preprocessor::HandlePragmaPopMacro(Token &PopMacroTok) {      PragmaPushMacroInfo.find(IdentInfo);    if (iter != PragmaPushMacroInfo.end()) {      // Forget the MacroInfo currently associated with IdentInfo. -    if (MacroDirective *CurrentMD = getMacroDirective(IdentInfo)) { -      MacroInfo *MI = CurrentMD->getMacroInfo(); +    if (MacroInfo *MI = getMacroInfo(IdentInfo)) {        if (MI->isWarnIfUnused())          WarnUnusedMacroLocs.erase(MI->getDefinitionLoc());        appendMacroDirective(IdentInfo, AllocateUndefMacroDirective(MessageLoc)); @@ -600,11 +600,9 @@ void Preprocessor::HandlePragmaPopMacro(Token &PopMacroTok) {      // Get the MacroInfo we want to reinstall.      MacroInfo *MacroToReInstall = iter->second.back(); -    if (MacroToReInstall) { +    if (MacroToReInstall)        // Reinstall the previously pushed macro. -      appendDefMacroDirective(IdentInfo, MacroToReInstall, MessageLoc, -                              /*isImported=*/false, /*Overrides*/None); -    } +      appendDefMacroDirective(IdentInfo, MacroToReInstall, MessageLoc);      // Pop PragmaPushMacroInfo stack.      iter->second.pop_back(); @@ -648,7 +646,7 @@ void Preprocessor::HandlePragmaIncludeAlias(Token &Tok) {      SourceLocation End;      if (ConcatenateIncludeName(FileNameBuffer, End))        return; // Diagnostic already emitted -    SourceFileName = FileNameBuffer.str(); +    SourceFileName = FileNameBuffer;    } else {      Diag(Tok, diag::warn_pragma_include_alias_expected_filename);      return; @@ -679,7 +677,7 @@ void Preprocessor::HandlePragmaIncludeAlias(Token &Tok) {      SourceLocation End;      if (ConcatenateIncludeName(FileNameBuffer, End))        return; // Diagnostic already emitted -    ReplaceFileName = FileNameBuffer.str(); +    ReplaceFileName = FileNameBuffer;    } else {      Diag(Tok, diag::warn_pragma_include_alias_expected_filename);      return; @@ -870,12 +868,22 @@ struct PragmaDebugHandler : public PragmaHandler {        LLVM_BUILTIN_TRAP;      } else if (II->isStr("parser_crash")) {        Token Crasher; +      Crasher.startToken();        Crasher.setKind(tok::annot_pragma_parser_crash); +      Crasher.setAnnotationRange(SourceRange(Tok.getLocation()));        PP.EnterToken(Crasher);      } else if (II->isStr("llvm_fatal_error")) {        llvm::report_fatal_error("#pragma clang __debug llvm_fatal_error");      } else if (II->isStr("llvm_unreachable")) {        llvm_unreachable("#pragma clang __debug llvm_unreachable"); +    } else if (II->isStr("macro")) { +      Token MacroName; +      PP.LexUnexpandedToken(MacroName); +      auto *MacroII = MacroName.getIdentifierInfo(); +      if (MacroII) +        PP.dumpMacroInfo(MacroII); +      else +        PP.Diag(MacroName, diag::warn_pragma_diagnostic_invalid);      } else if (II->isStr("overflow_stack")) {        DebugOverflowStack();      } else if (II->isStr("handle_crash")) { @@ -1029,12 +1037,8 @@ struct PragmaWarningHandler : public PragmaHandler {      PP.Lex(Tok);      IdentifierInfo *II = Tok.getIdentifierInfo(); -    if (!II) { -      PP.Diag(Tok, diag::warn_pragma_warning_spec_invalid); -      return; -    } -    if (II->isStr("push")) { +    if (II && II->isStr("push")) {        // #pragma warning( push[ ,n ] )        int Level = -1;        PP.Lex(Tok); @@ -1051,7 +1055,7 @@ struct PragmaWarningHandler : public PragmaHandler {        }        if (Callbacks)          Callbacks->PragmaWarningPush(DiagLoc, Level); -    } else if (II->isStr("pop")) { +    } else if (II && II->isStr("pop")) {        // #pragma warning( pop )        PP.Lex(Tok);        if (Callbacks) @@ -1061,23 +1065,40 @@ struct PragmaWarningHandler : public PragmaHandler {        //                  [; warning-specifier : warning-number-list...] )        while (true) {          II = Tok.getIdentifierInfo(); -        if (!II) { +        if (!II && !Tok.is(tok::numeric_constant)) {            PP.Diag(Tok, diag::warn_pragma_warning_spec_invalid);            return;          }          // Figure out which warning specifier this is. -        StringRef Specifier = II->getName(); -        bool SpecifierValid = -            llvm::StringSwitch<bool>(Specifier) -                .Cases("1", "2", "3", "4", true) -                .Cases("default", "disable", "error", "once", "suppress", true) -                .Default(false); +        bool SpecifierValid; +        StringRef Specifier; +        llvm::SmallString<1> SpecifierBuf; +        if (II) { +          Specifier = II->getName(); +          SpecifierValid = llvm::StringSwitch<bool>(Specifier) +                               .Cases("default", "disable", "error", "once", +                                      "suppress", true) +                               .Default(false); +          // If we read a correct specifier, snatch next token (that should be +          // ":", checked later). +          if (SpecifierValid) +            PP.Lex(Tok); +        } else { +          // Token is a numeric constant. It should be either 1, 2, 3 or 4. +          uint64_t Value; +          Specifier = PP.getSpelling(Tok, SpecifierBuf); +          if (PP.parseSimpleIntegerLiteral(Tok, Value)) { +            SpecifierValid = (Value >= 1) && (Value <= 4); +          } else +            SpecifierValid = false; +          // Next token already snatched by parseSimpleIntegerLiteral. +        } +          if (!SpecifierValid) {            PP.Diag(Tok, diag::warn_pragma_warning_spec_invalid);            return;          } -        PP.Lex(Tok);          if (Tok.isNot(tok::colon)) {            PP.Diag(Tok, diag::warn_pragma_warning_expected) << ":";            return; | 
