diff options
author | John McCall <rjmccall@apple.com> | 2011-09-30 05:12:12 +0000 |
---|---|---|
committer | John McCall <rjmccall@apple.com> | 2011-09-30 05:12:12 +0000 |
commit | 32f5fe1467c4f6cb9c3efe174cb6c8a374e6e149 (patch) | |
tree | 0045d1a99fc26a8c59d42184c0f322b6e97d7712 /clang/lib/Lex/Pragma.cpp | |
parent | 3360b411a5cddd9b7067147b3621d90b56dd90a8 (diff) | |
download | bcm5719-llvm-32f5fe1467c4f6cb9c3efe174cb6c8a374e6e149.tar.gz bcm5719-llvm-32f5fe1467c4f6cb9c3efe174cb6c8a374e6e149.zip |
Add explicit attributes to mark functions as having had their
CoreFoundation object-transfer properties audited, and add a #pragma
to cause them to be automatically applied to functions in a particular
span of code. This has to be implemented largely in the preprocessor
because of the requirement that the region be entirely contained in
a single file; that's hard to impose from the parser without registering
for a ton of callbacks.
llvm-svn: 140846
Diffstat (limited to 'clang/lib/Lex/Pragma.cpp')
-rw-r--r-- | clang/lib/Lex/Pragma.cpp | 55 |
1 files changed, 55 insertions, 0 deletions
diff --git a/clang/lib/Lex/Pragma.cpp b/clang/lib/Lex/Pragma.cpp index d855baf9e29..f6532c2175a 100644 --- a/clang/lib/Lex/Pragma.cpp +++ b/clang/lib/Lex/Pragma.cpp @@ -1005,6 +1005,60 @@ struct PragmaSTDC_UnknownHandler : public PragmaHandler { } }; +/// PragmaARCCFCodeAuditedHandler - +/// #pragma clang arc_cf_code_audited begin/end +struct PragmaARCCFCodeAuditedHandler : public PragmaHandler { + PragmaARCCFCodeAuditedHandler() : PragmaHandler("arc_cf_code_audited") {} + virtual void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer, + Token &NameTok) { + SourceLocation Loc = NameTok.getLocation(); + bool IsBegin; + + Token Tok; + + // Lex the 'begin' or 'end'. + PP.LexUnexpandedToken(Tok); + const IdentifierInfo *BeginEnd = Tok.getIdentifierInfo(); + if (BeginEnd && BeginEnd->isStr("begin")) { + IsBegin = true; + } else if (BeginEnd && BeginEnd->isStr("end")) { + IsBegin = false; + } else { + PP.Diag(Tok.getLocation(), diag::err_pp_arc_cf_code_audited_syntax); + return; + } + + // Verify that this is followed by EOD. + PP.LexUnexpandedToken(Tok); + if (Tok.isNot(tok::eod)) + PP.Diag(Tok, diag::ext_pp_extra_tokens_at_eol) << "pragma"; + + // The start location of the active audit. + SourceLocation BeginLoc = PP.getPragmaARCCFCodeAuditedLoc(); + + // The start location we want after processing this. + SourceLocation NewLoc; + + if (IsBegin) { + // Complain about attempts to re-enter an audit. + if (BeginLoc.isValid()) { + PP.Diag(Loc, diag::err_pp_double_begin_of_arc_cf_code_audited); + PP.Diag(BeginLoc, diag::note_pragma_entered_here); + } + NewLoc = Loc; + } else { + // Complain about attempts to leave an audit that doesn't exist. + if (!BeginLoc.isValid()) { + PP.Diag(Loc, diag::err_pp_unmatched_end_of_arc_cf_code_audited); + return; + } + NewLoc = SourceLocation(); + } + + PP.setPragmaARCCFCodeAuditedLoc(NewLoc); + } +}; + } // end anonymous namespace @@ -1028,6 +1082,7 @@ void Preprocessor::RegisterBuiltinPragmas() { AddPragmaHandler("clang", new PragmaDebugHandler()); AddPragmaHandler("clang", new PragmaDependencyHandler()); AddPragmaHandler("clang", new PragmaDiagnosticHandler("clang")); + AddPragmaHandler("clang", new PragmaARCCFCodeAuditedHandler()); AddPragmaHandler("STDC", new PragmaSTDC_FENV_ACCESSHandler()); AddPragmaHandler("STDC", new PragmaSTDC_CX_LIMITED_RANGEHandler()); |