aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/Parse/ParseDecl.cpp
diff options
context:
space:
mode:
authorEgor Zhdan <e_zhdan@apple.com>2024-01-17 13:13:10 +0000
committerGitHub <noreply@github.com>2024-01-17 13:13:10 +0000
commit77d21e758ea9665631b211abc0e424d7a7c44989 (patch)
treeebdc29cd47dabfd609b594d509737c352af54acf /clang/lib/Parse/ParseDecl.cpp
parent9791e5414960f92396582b9e9ee503ac15799312 (diff)
downloadllvm-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.cpp65
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