diff options
author | Egor Zhdan <e_zhdan@apple.com> | 2024-01-17 13:13:10 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-01-17 13:13:10 +0000 |
commit | 77d21e758ea9665631b211abc0e424d7a7c44989 (patch) | |
tree | ebdc29cd47dabfd609b594d509737c352af54acf /clang/lib/Parse/ParseDecl.cpp | |
parent | 9791e5414960f92396582b9e9ee503ac15799312 (diff) | |
download | llvm-77d21e758ea9665631b211abc0e424d7a7c44989.zip llvm-77d21e758ea9665631b211abc0e424d7a7c44989.tar.gz llvm-77d21e758ea9665631b211abc0e424d7a7c44989.tar.bz2 |
[APINotes] Upstream dependencies of Sema logic to apply API Notes to decls
This upstreams more of the Clang API Notes functionality that is
currently implemented in the Apple fork:
https://github.com/apple/llvm-project/tree/next/clang/lib/APINotes
This is the largest chunk of the API Notes functionality in the
upstreaming process. I will soon submit a follow-up patch to actually
enable usage of this functionality by having a Clang driver flag that
enables API Notes, along with tests.
Diffstat (limited to 'clang/lib/Parse/ParseDecl.cpp')
-rw-r--r-- | clang/lib/Parse/ParseDecl.cpp | 65 |
1 files changed, 65 insertions, 0 deletions
diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp index a106ce1..356e785 100644 --- a/clang/lib/Parse/ParseDecl.cpp +++ b/clang/lib/Parse/ParseDecl.cpp @@ -8051,6 +8051,71 @@ bool Parser::TryAltiVecTokenOutOfLine(DeclSpec &DS, SourceLocation Loc, return false; } +TypeResult Parser::ParseTypeFromString(StringRef TypeStr, StringRef Context, + SourceLocation IncludeLoc) { + // Consume (unexpanded) tokens up to the end-of-directive. + SmallVector<Token, 4> Tokens; + { + // Create a new buffer from which we will parse the type. + auto &SourceMgr = PP.getSourceManager(); + FileID FID = SourceMgr.createFileID( + llvm::MemoryBuffer::getMemBufferCopy(TypeStr, Context), SrcMgr::C_User, + 0, 0, IncludeLoc); + + // Form a new lexer that references the buffer. + Lexer L(FID, SourceMgr.getBufferOrFake(FID), PP); + L.setParsingPreprocessorDirective(true); + + // Lex the tokens from that buffer. + Token Tok; + do { + L.Lex(Tok); + Tokens.push_back(Tok); + } while (Tok.isNot(tok::eod)); + } + + // Replace the "eod" token with an "eof" token identifying the end of + // the provided string. + Token &EndToken = Tokens.back(); + EndToken.startToken(); + EndToken.setKind(tok::eof); + EndToken.setLocation(Tok.getLocation()); + EndToken.setEofData(TypeStr.data()); + + // Add the current token back. + Tokens.push_back(Tok); + + // Enter the tokens into the token stream. + PP.EnterTokenStream(Tokens, /*DisableMacroExpansion=*/false, + /*IsReinject=*/false); + + // Consume the current token so that we'll start parsing the tokens we + // added to the stream. + ConsumeAnyToken(); + + // Enter a new scope. + ParseScope LocalScope(this, 0); + + // Parse the type. + TypeResult Result = ParseTypeName(nullptr); + + // Check if we parsed the whole thing. + if (Result.isUsable() && + (Tok.isNot(tok::eof) || Tok.getEofData() != TypeStr.data())) { + Diag(Tok.getLocation(), diag::err_type_unparsed); + } + + // There could be leftover tokens (e.g. because of an error). + // Skip through until we reach the 'end of directive' token. + while (Tok.isNot(tok::eof)) + ConsumeAnyToken(); + + // Consume the end token. + if (Tok.is(tok::eof) && Tok.getEofData() == TypeStr.data()) + ConsumeAnyToken(); + return Result; +} + void Parser::DiagnoseBitIntUse(const Token &Tok) { // If the token is for _ExtInt, diagnose it as being deprecated. Otherwise, // the token is about _BitInt and gets (potentially) diagnosed as use of an |