comparison clang/lib/Parse/ParseCbC.cpp @ 152:e8a9b4f4d755

pull from 146
author anatofuz
date Wed, 11 Mar 2020 18:29:16 +0900
parents tools/clang/lib/Parse/ParseCbC.cpp@53f12981605a
children 70c77e05b61e
comparison
equal deleted inserted replaced
151:dbda48fb9435 152:e8a9b4f4d755
1 #ifndef noCbC
2
3 #include "clang/Parse/Parser.h"
4 #include "clang/Parse/RAIIObjectsForParser.h"
5 #include "clang/AST/ASTContext.h"
6 #include "clang/Basic/PrettyStackTrace.h"
7 #include "clang/Basic/TargetInfo.h"
8 #include "clang/Sema/DeclSpec.h"
9 #include "clang/Sema/PrettyDeclStackTrace.h"
10 #include "clang/Sema/Scope.h"
11 #include "clang/Sema/Lookup.h"
12 #include "clang/Lex/LiteralSupport.h"
13 #include "clang/AST/ASTConsumer.h"
14 #include "clang/Sema/SemaDiagnostic.h"
15
16 #include <sstream>
17 #include <string>
18 #include "CbCHelper.h"
19
20 using namespace clang;
21
22 /// The class which belong to this namespace is from other files' namespace.
23 /// Because those namespaces are unnamed namespaces, we can't access them.
24 /// So create this namespace and copy classes from those namespaces.
25 namespace ExternalSpace { // from ParseExpr.cpp , ParseStmt.cpp
26 class CastExpressionIdValidator : public CorrectionCandidateCallback {
27 public:
28 CastExpressionIdValidator(bool AllowTypes, bool AllowNonTypes)
29 : AllowNonTypes(AllowNonTypes) {
30 WantTypeSpecifiers = AllowTypes;
31 }
32
33 virtual bool ValidateCandidate(const TypoCorrection &candidate) {
34 NamedDecl *ND = candidate.getCorrectionDecl();
35 if (!ND)
36 return candidate.isKeyword();
37
38 if (isa<TypeDecl>(ND))
39 return WantTypeSpecifiers;
40 return AllowNonTypes;
41 }
42
43 private:
44 bool AllowNonTypes;
45 };
46
47 class StatementFilterCCC : public CorrectionCandidateCallback {
48 public:
49 StatementFilterCCC(Token nextTok) : NextToken(nextTok) {
50 WantTypeSpecifiers = nextTok.is(tok::l_paren) || nextTok.is(tok::less) ||
51 nextTok.is(tok::identifier) || nextTok.is(tok::star) ||
52 nextTok.is(tok::amp) || nextTok.is(tok::l_square);
53 WantExpressionKeywords = nextTok.is(tok::l_paren) ||
54 nextTok.is(tok::identifier) ||
55 nextTok.is(tok::arrow) || nextTok.is(tok::period);
56 WantRemainingKeywords = nextTok.is(tok::l_paren) || nextTok.is(tok::semi) ||
57 nextTok.is(tok::identifier) ||
58 nextTok.is(tok::l_brace);
59 WantCXXNamedCasts = false;
60 }
61
62 virtual bool ValidateCandidate(const TypoCorrection &candidate) {
63 if (FieldDecl *FD = candidate.getCorrectionDeclAs<FieldDecl>())
64 return !candidate.getCorrectionSpecifier() || isa<ObjCIvarDecl>(FD);
65 if (NextToken.is(tok::equal))
66 return candidate.getCorrectionDeclAs<VarDecl>();
67 if (NextToken.is(tok::period) &&
68 candidate.getCorrectionDeclAs<NamespaceDecl>())
69 return false;
70 return CorrectionCandidateCallback::ValidateCandidate(candidate);
71 }
72
73 private:
74 Token NextToken;
75 };
76 }
77
78
79 /// Prepare__retForGotoWithTheEnvExpr - Prepare __CbC_return, code segment for returning and some necessary statements.
80 /// It is called when the parser find __return and statements are put into complex statement.
81 ///
82 /// examples which are created:
83 /// complex statement:
84 /// ({
85 /// __code (*__CbC_return)(return_type, void*);
86 /// __CbC_return = code_segment_for_return;
87 /// __CbC_return;
88 /// });
89 /// code segment:
90 /// __code ret(return_type retval, void *env){
91 /// *(return_type)((struct __CbC_env *)(env))->ret_p = retval;
92 /// longjmp((int*)(((struct __CbC_env *)env)->env),1);
93 /// }
94 ExprResult Parser::Prepare__retForGotoWithTheEnvExpr(){
95
96 if (isVoidFunction()) { // error check : function type is void or not.
97 unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error, "continuation with the environment cannot use in the void function");
98 Diag(Tok, DiagID);
99 return ExprError();
100 }
101
102 StmtResult innerRes;
103 SourceLocation Loc = Tok.getLocation();
104 IdentifierInfo *__CbC_retII = CreateIdentifierInfo(__CBC_RETURN_NAME, Loc);
105 IdentifierInfo *retcsII = CreateUniqueIdentifierInfo(__CBC_RET_CODE_BASE_NAME, Loc);
106 Create__CbC_envStruct(Loc, AS_none);
107
108 Actions.ActOnStartStmtExpr();
109 StmtResult CompoundStmtRes;
110 ParseScope CompoundScope(this, Scope::DeclScope);
111 PrettyStackTraceLoc CrashInfo(PP.getSourceManager(),Loc,"in compound statement ('{}')");
112 StmtVector CompoundStmts;
113
114 // create code segment for return to C's function
115 CreateRetCS(retcsII);
116
117 // __code (*__CbC_return)();
118 innerRes = CreateDeclStmt(__CbC_retII, true, false, DeclSpec::TST___code);
119 if (innerRes.isUsable())
120 CompoundStmts.push_back(innerRes.get());
121
122 // __CbC_return = ret;
123 innerRes = CreateAssignmentStmt(__CbC_retII, retcsII);
124 if (innerRes.isUsable())
125 CompoundStmts.push_back(innerRes.get());
126
127 // __CbC_return;
128 innerRes = CreateComplexStmtRet(__CbC_retII, false);
129 if (innerRes.isUsable())
130 CompoundStmts.push_back(innerRes.get());
131
132 CompoundStmtRes = Actions.ActOnCompoundStmt(Loc,Loc,CompoundStmts,true);
133 ConsumeToken(); // eat the '__return'.
134 return Actions.ActOnStmtExpr(Loc, CompoundStmtRes.get(), Loc);
135 }
136
137 /// Prepare__envForGotoWithTheEnvExpr - Prepare __CbC_environment, struct __CbC_env and some necessary statements.
138 /// It is called when the parser find __environment and statements are put into complex statement.
139 ///
140 /// examples which are created:
141 /// complex statement:
142 /// ({
143 /// volatile struct __CbC_env __CbC_environment;
144 /// jmp_buf env_buf;
145 /// return_type retval;
146 /// __CbC_environment.ret_p = &retval;
147 /// __CbC_environment.env = &env_buf;
148 /// if (setjmp(__CbC_environment.env)){
149 /// return retval;
150 /// }
151 /// &__CbC_environment;
152 /// });
153 /// struct __CbC_env:
154 /// struct __CbC_env{
155 /// void *ret_p,*env;
156 /// }
157 ExprResult Parser::Prepare__envForGotoWithTheEnvExpr(){
158
159 if (isVoidFunction()) { // error check : function type is void or not.
160 unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error, "continuation with the environment cannot use in the void function");
161 Diag(Tok, DiagID);
162 return ExprError();
163 }
164
165 StmtResult innerRes;
166 SourceLocation Loc = Tok.getLocation();
167 IdentifierInfo *bufII = CreateIdentifierInfo(__CBC_BUF_NAME, Loc);
168 IdentifierInfo *retvalII = CreateIdentifierInfo(__CBC_RETVAL_NAME, Loc);
169 IdentifierInfo *structII = CreateIdentifierInfo(__CBC_STRUCT_NAME, Loc);
170 IdentifierInfo *__CbC_envII = CreateIdentifierInfo(__CBC_ENVIRONMENT_NAME, Loc);
171 IdentifierInfo *envII = CreateIdentifierInfo(__CBC_STRUCT_ENV_NAME, Loc);
172 IdentifierInfo *ret_pII = CreateIdentifierInfo(__CBC_STRUCT_POINTER_NAME, Loc);
173 Create__CbC_envStruct(Loc, AS_none);
174 Actions.ActOnStartStmtExpr();
175 ParseScope CompoundScope(this, Scope::DeclScope);
176 PrettyStackTraceLoc CrashInfo(PP.getSourceManager(),Loc,"in compound statement ('{}')");
177 StmtVector CompoundStmts;
178 ExprResult Result(true);
179
180 // struct __CbC_env __CbC_environment;
181 innerRes = CreateDeclStmt(__CbC_envII, false, false, DeclSpec::TST_struct, structII, DeclSpec::TQ_volatile);
182 if (innerRes.isUsable())
183 CompoundStmts.push_back(innerRes.get());
184
185 // returnType retval;
186 innerRes = CreateDeclStmt(retvalII, false, true);
187 if (innerRes.isUsable())
188 CompoundStmts.push_back(innerRes.get());
189
190 // jmp_buf env_buf;
191 innerRes = CreateDeclStmt(bufII, false, false, DeclSpec::TST_typename, CreateIdentifierInfo("jmp_buf", Loc));
192 if (innerRes.isUsable())
193 CompoundStmts.push_back(innerRes.get());
194
195 // __CbC_environment.ret_p = &retval;
196 innerRes = CreateAssignmentStmt(__CbC_envII, retvalII, true, true, ret_pII);
197 if (innerRes.isUsable())
198 CompoundStmts.push_back(innerRes.get());
199
200 // __CbC_environment.env = env_buf;
201 innerRes = CreateAssignmentStmt(__CbC_envII, bufII, true, false, envII);
202 if (innerRes.isUsable())
203 CompoundStmts.push_back(innerRes.get());
204
205 // create statements of setjmp
206 innerRes = CreateSjForContinuationWithTheEnv();
207 if (innerRes.isUsable())
208 CompoundStmts.push_back(innerRes.get());
209
210 // __CbC_environment;
211 innerRes = CreateComplexStmtRet(__CbC_envII, true);
212 if (innerRes.isUsable())
213 CompoundStmts.push_back(innerRes.get());
214
215 StmtResult CompoundStmtRes = Actions.ActOnCompoundStmt(Loc,Loc,CompoundStmts,true);
216 ConsumeToken(); // eat the '__environment'.
217 Result = Actions.ActOnStmtExpr(Loc, CompoundStmtRes.get(), Loc);
218
219 // cast
220 ParsedType CastTy;
221 DeclSpec void_DS(AttrFactory);
222 setTST(&void_DS, DeclSpec::TST_void);
223 Declarator DeclaratorInfo(void_DS, DeclaratorContext::TypeNameContext);
224 DeclSpec star_DS(AttrFactory);
225 star_DS.Finish(Actions, Actions.getASTContext().getPrintingPolicy());
226 DeclaratorInfo.ExtendWithDeclSpec(star_DS);
227 DeclaratorInfo.SetIdentifier(nullptr, Tok.getLocation());
228 DeclaratorInfo.AddTypeInfo(DeclaratorChunk::getPointer(star_DS.getTypeQualifiers(), Loc,star_DS.getConstSpecLoc(),star_DS.getVolatileSpecLoc(),
229 star_DS.getRestrictSpecLoc(),star_DS.getAtomicSpecLoc(),star_DS.getUnalignedSpecLoc()),star_DS.getAttributes(),SourceLocation());
230 return Actions.ActOnCastExpr(getCurScope(), Loc, DeclaratorInfo, CastTy,Loc, Result.get());
231
232 }
233
234 /// CreateAssignmentStmt - Create assignment statement such as "aaa = bbb;", "auaua = llll;", etc.
235 /// It can create 4 kinds of statement.
236 /// 1. common assignment statement:
237 /// variable '=' variable ';'
238 /// 2. LHS variable is member of struct:
239 /// structVar '.' member '=' variable ';'
240 /// 3. RHS variable is address of operand:
241 /// variable '=' '&' variable ';'
242 /// 4. 2+3:
243 /// structVar '.' member '=' '&' variable ';'
244 StmtResult Parser::CreateAssignmentStmt(IdentifierInfo* LHSII, IdentifierInfo* RHSII, bool LHSisMemberAccess, bool RHShasAmp,
245 IdentifierInfo* extraLHSII, IdentifierInfo* extraRHSII){
246 ExprResult Expr,LHS,RHS;
247
248 Token Next,LHSToken;
249 SourceLocation Loc = Tok.getLocation();
250 CXXScopeSpec SS;
251 Next.startToken();
252 Next.setKind(tok::period);
253 LHSToken.startToken();
254 LHSToken.setLocation(Loc);
255 LHSToken.setIdentifierInfo(LHSII);
256 LHSToken.setKind(tok::annot_primary_expr);
257 std::unique_ptr<ExternalSpace::StatementFilterCCC> Validator(new ExternalSpace::StatementFilterCCC(Next));
258 Sema::NameClassification Classification = Actions.ClassifyName(getCurScope(), SS, LHSII, Loc, Next, false, SS.isEmpty() ? std::move(Validator) : 0);
259 setExprAnnotation(LHSToken, Classification.getExpression());
260 LHSToken.setAnnotationEndLoc(Loc);
261 PP.AnnotateCachedTokens(LHSToken);
262
263 LHS = getExprAnnotation(LHSToken);
264
265 if (LHSisMemberAccess)
266 LHS = LookupMemberAndBuildExpr(extraLHSII, LHS.get(), false);
267
268 RHS = LookupNameAndBuildExpr(RHSII);
269 if (RHShasAmp)
270 RHS = Actions.ActOnUnaryOp(getCurScope(), Loc, tok::amp, RHS.get());
271
272 Expr = Actions.ActOnBinOp(getCurScope(), Loc,tok::equal,LHS.get(),RHS.get());
273
274 return Actions.ActOnExprStmt(Expr);
275 }
276
277 /// CreateDeclStmt - Create declaration statement such as "int aaa;".
278 /// If isRetCS is true, create code segment for return to C's function. And Name is name of code segment.
279 /// If copyType is true, type of variable is copied from callee.
280 StmtResult Parser::CreateDeclStmt(IdentifierInfo *II, bool isRetCS, bool copyType, DeclSpec::TST valueType, IdentifierInfo* Name, DeclSpec::TQ TQ){
281 const PrintingPolicy &Policy = Actions.getASTContext().getPrintingPolicy();
282 SourceLocation Loc = Tok.getLocation();
283 DeclGroupPtrTy DeclGPT;
284 ParsingDeclSpec DS(*this);
285 DeclSpec *DSp;
286 DSp = &DS;
287
288 setTST(&DS, valueType, Name, TQ);
289 ParsingDeclarator D(*this, DS, static_cast<DeclaratorContext>(DeclaratorContext::BlockContext));
290 D.SetIdentifier(II, Loc);
291
292 if (isRetCS) {
293 D.setEllipsisLoc(SourceLocation());
294 bool hadGroupingParens = D.hasGroupingParens();
295 D.setGroupingParens(true);
296 D.SetRangeEnd(Loc);
297 DeclSpec FDS(AttrFactory);
298 DS.Finish(Actions, Policy);
299
300 D.AddTypeInfo(DeclaratorChunk::getPointer(FDS.getTypeQualifiers(), Loc, FDS.getConstSpecLoc(), FDS.getVolatileSpecLoc(),
301 FDS.getRestrictSpecLoc(), DS.getAtomicSpecLoc(), FDS.getUnalignedSpecLoc()), FDS.getAttributes(), SourceLocation());
302 D.setGroupingParens(hadGroupingParens);
303
304
305 ParseScope PrototypeScope(this,Scope::FunctionPrototypeScope|Scope::DeclScope|
306 (D.isFunctionDeclaratorAFunctionDeclaration() ? Scope::FunctionDeclarationScope : 0));
307 bool HasProto = false;
308 SmallVector<DeclaratorChunk::ParamInfo, 16> ParamInfo;
309 SourceLocation EllipsisLoc, RefQualifierLoc, ConstQualifierLoc, VolatileQualifierLoc, RestrictQualifierLoc;
310 DeclSpec FPDS(AttrFactory);
311 bool RefQualifierIsLValueRef = true;
312 ExceptionSpecificationType ESpecType = EST_None;
313 SourceRange ESpecRange;
314 SmallVector<ParsedType, 2> DynamicExceptions;
315 SmallVector<SourceRange, 2> DynamicExceptionRanges;
316 ExprResult NoexceptExpr;
317 CachedTokens *ExceptionSpecTokens = 0;
318 ParsedAttributes FnAttrs(AttrFactory);
319 TypeResult TrailingReturnType;
320
321 ParmVarDecl *Param;
322 FunctionDecl *CurFunctionDecl = Actions.getCurFunctionDecl();
323 QualType CurFuncResQT = CurFunctionDecl->getReturnType();
324 TypeSourceInfo *CurFuncTI = Actions.Context.CreateTypeSourceInfo(CurFuncResQT);
325
326 Param = CreateParam();
327 Param->setTypeSourceInfo(CurFuncTI);
328 Param->setType(CurFuncResQT);
329 ParamInfo.push_back(DeclaratorChunk::ParamInfo(0, Loc, Param, 0));
330 Param = CreateParam(0, 1, DeclSpec::TST_void);
331 ParamInfo.push_back(DeclaratorChunk::ParamInfo(0, Loc, Param, 0));
332 HasProto = true;
333
334 D.AddTypeInfo(DeclaratorChunk::getFunction(HasProto, false, Loc, ParamInfo.data(),
335 ParamInfo.size(), EllipsisLoc, Loc, FPDS.getTypeQualifiers(),
336 RefQualifierIsLValueRef, RefQualifierLoc, ConstQualifierLoc,
337 VolatileQualifierLoc, RefQualifierLoc, SourceLocation(),
338 ESpecType, ESpecRange.getBegin(),
339 DynamicExceptions.data(), DynamicExceptionRanges.data(),
340 DynamicExceptions.size(),
341 NoexceptExpr.isUsable() ? NoexceptExpr.get() : 0, ExceptionSpecTokens, None, Loc, Loc, D, TrailingReturnType),
342 FnAttrs, Loc);
343 PrototypeScope.Exit();
344 DSp = &FDS;
345 }
346
347 SmallVector<Decl *, 8> DeclsInGroup;
348 Decl *FirstDecl;
349
350 if (copyType)
351 FirstDecl = HandleDeclAndChangeDeclType(D);
352 else
353 FirstDecl = ParseDeclarationAfterDeclaratorAndAttributes(D);
354
355 D.complete(FirstDecl);
356 DeclsInGroup.push_back(FirstDecl);
357 DeclGPT = Actions.FinalizeDeclaratorGroup(getCurScope(), *DSp, DeclsInGroup);
358 return Actions.ActOnDeclStmt(DeclGPT, Loc, Loc);
359 }
360
361
362 /// handleDeclAndChangeDeclType - This function imitated Parser::ParseDeclarationAfterDeclaratorAndAttributes() and Sema::ActOnDeclarator().
363 /// The origins get Type from Declarator but this function get Type from current function.
364 /// It is useful for CbC to create statements for the continuation with the environments.
365 Decl* Parser::HandleDeclAndChangeDeclType(Declarator &D) {
366 D.setFunctionDefinitionKind(FDK_Declaration);
367 DeclarationNameInfo NameInfo = Actions.GetNameForDeclarator(D);
368 DeclContext *DC = Actions.CurContext;
369 QualType R = Actions.getCurFunctionDecl()->getReturnType(); // copy a type
370 TypeSourceInfo *TInfo = Actions.Context.CreateTypeSourceInfo(R); // copy a type infomation
371 Scope *S = getCurScope();
372 LookupResult Previous(Actions, NameInfo, Actions.LookupOrdinaryName, Actions.ForVisibleRedeclaration);
373 bool IsLinkageLookup = false;
374 bool CreateBuiltins = false;
375
376 // If the declaration we're planning to build will be a function
377 // or object with linkage, then look for another declaration with
378 // linkage (C99 6.2.2p4-5 and C++ [basic.link]p6).
379 //
380 // If the declaration we're planning to build will be declared with
381 // external linkage in the translation unit, create any builtin with
382 // the same name.
383 if (R->isFunctionType()) {
384 IsLinkageLookup = true;
385 CreateBuiltins =
386 Actions.CurContext->getEnclosingNamespaceContext()->isTranslationUnit();
387 } else if (Actions.CurContext->getRedeclContext()->isTranslationUnit())
388 CreateBuiltins = true;
389
390 if (IsLinkageLookup)
391 Previous.clear(Actions.LookupRedeclarationWithLinkage);
392
393 Actions.LookupName(Previous, S, CreateBuiltins);
394
395 // In C++, the previous declaration we find might be a tag type
396 // (class or enum). In this case, the new declaration will hide the
397 // tag type. Note that this does does not apply if we're declaring a
398 // typedef (C++ [dcl.typedef]p4).
399 if (Previous.isSingleTagDecl())
400 Previous.clear();
401 NamedDecl *New;
402 bool AddToScope = true;
403 if (R->isFunctionType()) {
404 New = Actions.ActOnFunctionDeclarator(S, D, DC, TInfo, Previous,
405 MultiTemplateParamsArg(), AddToScope);
406 } else {
407 New = Actions.ActOnVariableDeclarator(S, D, DC, TInfo, Previous,
408 MultiTemplateParamsArg(), AddToScope);
409 }
410
411 if (New->getDeclName() && AddToScope) {
412 // Only make a locally-scoped extern declaration visible if it is the first
413 // declaration of this entity. Qualified lookup for such an entity should
414 // only find this declaration if there is no visible declaration of it.
415 bool AddToContext = !D.isRedeclaration() || !New->isLocalExternDecl();
416 Actions.PushOnScopeChains(New, S, AddToContext);
417 if (!AddToContext)
418 Actions.CurContext->addHiddenDecl(New);
419 }
420
421 return New;
422 }
423
424 /// CreateSjForContinuationWithEnv - Create statements of setjmp for continuation with the environment.
425 /// code example:
426 /// if (setjmp(__CbC_environment.env)){
427 /// return retval;
428 /// }
429 StmtResult Parser::CreateSjForContinuationWithTheEnv(){
430 SourceLocation Loc = Tok.getLocation();
431 StmtResult IfRes;
432 ParseScope IfScope(this, Scope::DeclScope | Scope::ControlScope, true/* C99 or CXX */);
433 ExprResult CondExp;
434 StmtResult InitStmt;
435 Sema::ConditionResult Cond;
436
437 CondExp = LookupNameAndBuildExpr(CreateIdentifierInfo("__builtin_setjmp", Loc));
438 ExprVector ArgExprs;
439 ExprResult __envExprRes = CondExp.get();
440
441 __envExprRes = LookupNameAndBuildExpr(CreateIdentifierInfo(__CBC_ENVIRONMENT_NAME, Loc));
442 __envExprRes = LookupMemberAndBuildExpr(CreateIdentifierInfo(__CBC_STRUCT_ENV_NAME, Loc), __envExprRes.get(), false);
443
444 ArgExprs.push_back(__envExprRes.get());
445 CondExp = Actions.ActOnCallExpr(getCurScope(), CondExp.get(), Loc, ArgExprs, Loc, 0);
446 Cond = Actions.ActOnCondition(getCurScope(), Loc, CondExp.get(), Sema::ConditionKind::Boolean);
447
448
449 ParseScope InnerScope(this, Scope::DeclScope,false);
450 SourceLocation InnerStatementTrailingElseLoc;
451
452 StmtResult StmtRes;
453 ParseScope CompoundScope(this, Scope::DeclScope);
454 PrettyStackTraceLoc CrashInfo(PP.getSourceManager(),Loc,"in create setjmp statement for CbC");
455 StmtVector innerStmts;
456 StmtResult innerStmtRes;
457 ExprResult innerExprRes;
458 innerExprRes = LookupNameAndBuildExpr(CreateIdentifierInfo(__CBC_RETVAL_NAME, Loc));
459 innerStmtRes = Actions.ActOnReturnStmt(Loc, innerExprRes.get(), getCurScope());
460 if (innerStmtRes.isUsable())
461 innerStmts.push_back(innerStmtRes.get());
462 StmtRes = Actions.ActOnCompoundStmt(Loc, Loc,innerStmts, false);
463 StmtResult ThenStmt(StmtRes);
464 InnerScope.Exit();
465 IfScope.Exit();
466 StmtResult ElseStmt;
467 IfRes = Actions.ActOnIfStmt(Loc, false, CondExp.get(), Cond, ThenStmt.get(),Loc, ElseStmt.get());
468 return IfRes;
469 }
470
471
472 /// LookupNameAndBuildExpr - Look up name, create ExprResult and return it.
473 ExprResult Parser::LookupNameAndBuildExpr(IdentifierInfo *II, bool IsAddressOfOperand){
474 SourceLocation Loc = Tok.getLocation();
475 UnqualifiedId Name;
476 CXXScopeSpec SS;
477 SourceLocation TemplateKWLoc;
478 std::unique_ptr<ExternalSpace::CastExpressionIdValidator> Validator(new ExternalSpace::CastExpressionIdValidator(false,true));
479 Name.setIdentifier(II, Loc);
480 return Actions.ActOnIdExpression(getCurScope(), SS, TemplateKWLoc, Name, false, IsAddressOfOperand, std::move(Validator));
481 }
482
483 /// LookupMemberAndBuildExpr - Look up member name, create ExprResult and return it.
484 /// If IsArrow is true, the name is accessed by arrow operand.
485 ExprResult Parser::LookupMemberAndBuildExpr(IdentifierInfo *II, Expr* Base, bool IsArrow){
486 SourceLocation Loc = Tok.getLocation();
487 CXXScopeSpec SS;
488 UnqualifiedId Name;
489 SourceLocation TemplateKWLoc;
490 tok::TokenKind OpKind = (IsArrow ? tok::arrow : tok::period);
491 Name.setIdentifier(II,Loc);
492 return Actions.ActOnMemberAccessExpr(getCurScope(), Base, Loc, OpKind, SS, TemplateKWLoc, Name, nullptr);
493 }
494
495
496 /// Create__CbC_envStruct - This method create "struct __CbC_env" which is used to continuation with environment.
497 /// If the __CbC_env has been already defined, it doesn't create __CbC_env again.
498 /// The example of struct which is created :
499 /// struct __CbC_env{
500 /// void *ret_p,*env;
501 /// };
502 void Parser::Create__CbC_envStruct(SourceLocation Loc, AccessSpecifier AS) {
503
504 IdentifierInfo *Name = CreateIdentifierInfo(__CBC_STRUCT_NAME, Loc);
505 // Check previous definition. If the __CbC_env has been already defined, we have not to create again.
506 LookupResult Previous(Actions, Name, Loc, Actions.LookupTagName, Actions.ForVisibleRedeclaration);
507 if(Actions.LookupName(Previous, getCurScope()))
508 return;
509
510 Scope *SavedScope = getCurScope();
511 DeclContext *SavedContext = Actions.CurContext;
512 sema::FunctionScopeInfo *SavedFSI = Actions.FunctionScopes.pop_back_val();
513
514 Actions.CurContext = static_cast<DeclContext *>(Actions.Context.getTranslationUnitDecl());
515 Scope *TopScope = getCurScope();
516 while(TopScope->getParent() != NULL)
517 TopScope = TopScope->getParent();
518 Actions.CurScope = TopScope;
519
520 ParsingDeclSpec SDS(*this);
521 SDS.SetRangeStart(Loc);
522 SDS.SetRangeEnd(Loc);
523 DeclSpec::TST TagType = DeclSpec::TST_struct;
524 DeclResult TagOrTempResult = true;
525 bool Owned = false;
526 bool IsDependent = false;
527 ParsedAttributesWithRange attrs(AttrFactory);
528 MultiTemplateParamsArg TParams;
529
530 TagOrTempResult = Actions.ActOnTag(getCurScope(), TagType, Sema::TUK_Definition, Loc,
531 SDS.getTypeSpecScope(), Name, Loc, attrs.getList(), AS,
532 SDS.getModulePrivateSpecLoc(), TParams, Owned, IsDependent,
533 SourceLocation(), false, clang::TypeResult(), false, false);
534
535 Decl *TagDecl = TagOrTempResult.get();
536 PrettyDeclStackTraceEntry CrashInfo(Actions, TagDecl, Loc, "parsing struct/union body");
537 ParseScope StructScope(this, Scope::ClassScope|Scope::DeclScope);
538 Actions.ActOnTagStartDefinition(getCurScope(), TagDecl);
539 SmallVector<Decl *, 32> FieldDecls;
540
541 FieldDecls.push_back(Create__CbC_envBody(TagDecl, DeclSpec::TST_void, Loc, __CBC_STRUCT_POINTER_NAME));
542 FieldDecls.push_back(Create__CbC_envBody(TagDecl, DeclSpec::TST_void, Loc, __CBC_STRUCT_ENV_NAME));
543
544 Actions.ActOnFields(getCurScope(),Loc, TagDecl, FieldDecls,Loc, Loc,attrs.getList());
545 StructScope.Exit();
546 Actions.ActOnTagFinishDefinition(getCurScope(), TagDecl, Loc);
547
548 Actions.CurScope = SavedScope;
549 Actions.CurContext = SavedContext;
550 Actions.FunctionScopes.push_back(SavedFSI);
551 }
552
553 /// Create__CbC_envBody - Create void type pointer ret_p and env which are member of __CbC_env.
554 Decl* Parser::Create__CbC_envBody(Decl* TagDecl, DeclSpec::TST T, SourceLocation Loc, const char* Name){
555 const PrintingPolicy &Policy = Actions.getASTContext().getPrintingPolicy();
556 ParsingDeclSpec PDS(*this);
557 setTST(&PDS, T);
558 SourceLocation CommaLoc;
559 ParsingFieldDeclarator DeclaratorInfo(*this, PDS);
560 DeclaratorInfo.D.setCommaLoc(CommaLoc);
561 DeclaratorInfo.D.SetRangeEnd(Loc);
562 DeclSpec DS(AttrFactory);
563 DS.Finish(Actions, Policy);
564 DeclaratorInfo.D.SetIdentifier(CreateIdentifierInfo(Name, Loc),Loc);
565
566 DeclaratorInfo.D.AddTypeInfo(DeclaratorChunk::getPointer(DS.getTypeQualifiers(), Loc,DS.getConstSpecLoc(),
567 DS.getVolatileSpecLoc(),DS.getRestrictSpecLoc(), DS.getAtomicSpecLoc(), DS.getUnalignedSpecLoc()),
568 DS.getAttributes(),SourceLocation());
569 Decl *Field = Actions.ActOnField(getCurScope(), TagDecl,
570 DeclaratorInfo.D.getDeclSpec().getSourceRange().getBegin(),
571 DeclaratorInfo.D, DeclaratorInfo.BitfieldSize);
572 DeclaratorInfo.complete(Field);
573 return Field;
574 }
575
576 /// CreateIdentifierInfo - Create IdentifierInfo from char pointer.
577 /// usage :
578 /// IdentifierInfo *II = CreateIdentifierInfo(IIName, Location);
579 IdentifierInfo* Parser::CreateIdentifierInfo(const char* Name, SourceLocation Loc) {
580 int length = strlen(Name);
581 Token TokenForII;
582 TokenForII.startToken();
583 TokenForII.setLocation(Loc);
584 TokenForII.setLength(length);
585 TokenForII.setKind(tok::raw_identifier);
586 TokenForII.setRawIdentifierData(Name);
587 IdentifierInfo *II;
588 II = PP.getIdentifierInfo(TokenForII.getRawIdentifier());
589 TokenForII.setIdentifierInfo(II);
590 TokenForII.setKind(II->getTokenID());
591 return II;
592 }
593
594 /// CreateUniqueIdentifierInfo - Create unique IdentifierInfo.
595 /// IdentifierInfos have unique name which were created by this function.
596 /// Naming conventions :
597 /// current 'function name' '..' 'variable name' 'uniqueID'
598 /// For example, if current function's name is 'main' and variable name is 'auaua', IdentifierInfo's name is 'main..auaua'.
599 IdentifierInfo* Parser::CreateUniqueIdentifierInfo(const char* Name, SourceLocation Loc){
600 IdentifierInfo *II;
601 std::ostringstream os;
602
603 os << curFuncName << ".." /* separator */ << Name << UniqueId;
604 II = CreateIdentifierInfo(os.str().c_str(), Loc);
605 UniqueId++; // Modify the unique ID.
606 return II;
607 }
608
609
610 /// CreateRetCS - Create code segment which is used for continuation with the environment.
611 /// create these codes:
612 /// __code ret(return_type retval, void *env){
613 /// *(return_type)((struct CbC_environment *)(env))->ret_p = n;
614 /// longjmp((void*)(((struct __CbC_environment *)env)->env),1);
615 /// }
616 void Parser::CreateRetCS(IdentifierInfo *csName){
617 const PrintingPolicy &Policy = Actions.getASTContext().getPrintingPolicy();
618 QualType CurFuncResQT = Actions.getCurFunctionDecl()->getReturnType();
619
620 Scope *SavedScope = getCurScope();
621 DeclContext *SavedContext = Actions.CurContext;
622 TypeSourceInfo *CurFuncTI = Actions.Context.CreateTypeSourceInfo(CurFuncResQT);
623 sema::FunctionScopeInfo *SavedFSI = Actions.FunctionScopes.pop_back_val();
624
625 Actions.CurContext = static_cast<DeclContext *>(Actions.Context.getTranslationUnitDecl());
626 Scope *TopScope = getCurScope();
627 while(TopScope->getParent() != NULL)
628 TopScope = TopScope->getParent();
629 Actions.CurScope = TopScope;
630
631 DeclGroupPtrTy returnDecl = DeclGroupPtrTy();
632 SourceLocation Loc = Tok.getLocation();
633 ParsingDeclSpec PDS(*this);
634 setTST(&PDS, DeclSpec::TST___code);
635 ParsingDeclarator D(*this, PDS, static_cast<DeclaratorContext>(DeclaratorContext::FileContext));
636 D.SetIdentifier(csName, Loc);
637 ParseScope PrototypeScope(this,Scope::FunctionPrototypeScope|Scope::DeclScope|Scope::FunctionDeclarationScope);
638 bool IsAmbiguous = false;
639 bool HasProto = true;
640 SmallVector<DeclaratorChunk::ParamInfo, 16> ParamInfo;
641 SourceLocation EllipsisLoc, RefQualifierLoc, ConstQualifierLoc, VolatileQualifierLoc, RestrictQualifierLoc;
642 DeclSpec FDS(AttrFactory);
643 bool RefQualifierIsLValueRef = true;
644 ExceptionSpecificationType ESpecType = EST_None;
645 SourceRange ESpecRange;
646 SmallVector<ParsedType, 2> DynamicExceptions;
647 SmallVector<SourceRange, 2> DynamicExceptionRanges;
648 ExprResult NoexceptExpr;
649 CachedTokens *ExceptionSpecTokens = 0;
650 ParsedAttributes FnAttrs(AttrFactory);
651 TypeResult TrailingReturnType;
652 ParmVarDecl *Param;
653
654 IdentifierInfo *retvalII = CreateIdentifierInfo(__CBC_RETVAL_NAME, Loc);
655 Param = CreateParam(retvalII);
656 Param->setTypeSourceInfo(CurFuncTI);
657 Param->setType(CurFuncResQT);
658
659 ParamInfo.push_back(DeclaratorChunk::ParamInfo(retvalII, Loc, Param, 0));
660 IdentifierInfo *envII = CreateIdentifierInfo(__CBC_STRUCT_ENV_NAME, Loc);
661 Param = CreateParam(envII, 1, DeclSpec::TST_void);
662 ParamInfo.push_back(DeclaratorChunk::ParamInfo(envII, Loc, Param, 0));
663
664 D.AddTypeInfo(DeclaratorChunk::getFunction(HasProto, IsAmbiguous, Loc, ParamInfo.data(), ParamInfo.size(), EllipsisLoc, Loc,
665 FDS.getTypeQualifiers(), RefQualifierIsLValueRef, RefQualifierLoc, ConstQualifierLoc,
666 VolatileQualifierLoc, RestrictQualifierLoc, SourceLocation(),
667 ESpecType, ESpecRange.getBegin(),
668 DynamicExceptions.data(), DynamicExceptionRanges.data(), DynamicExceptions.size(),
669 NoexceptExpr.isUsable() ? NoexceptExpr.get() : 0, ExceptionSpecTokens, None,
670 Loc, Loc, D, TrailingReturnType), FnAttrs, Loc);
671 PrototypeScope.Exit();
672
673 Decl *TheDecl;
674 ParseScope BodyScope(this, Scope::FnScope|Scope::DeclScope);
675 Sema::SkipBodyInfo SkipBody;
676 const ParsedTemplateInfo &TemplateInfo = ParsedTemplateInfo();
677 Decl *BodyRes = Actions.ActOnStartOfFunctionDef(getCurScope(), D,
678 TemplateInfo.TemplateParams ? *TemplateInfo.TemplateParams : MultiTemplateParamsArg(),
679 &SkipBody);
680
681 D.complete(BodyRes);
682 D.getMutableDeclSpec().abort();
683 Actions.ActOnDefaultCtorInitializers(BodyRes);
684 StmtResult FnBody;
685 StmtVector FnStmts;
686 StmtResult innerR;
687 ExprResult retvalAssginmentExpr,LHS;
688 ExprVector ArgExprs;
689 CommaLocsTy CommaLocs;
690 DeclSpec envDS(AttrFactory);
691 IdentifierInfo *structName = CreateIdentifierInfo(__CBC_STRUCT_NAME, Loc);
692 setTST(&envDS, DeclSpec::TST_struct, structName);
693
694 Declarator envDInfo(envDS, DeclaratorContext::TypeNameContext);
695 envDInfo.SetRangeEnd(Loc);
696 DeclSpec starDS(AttrFactory);
697 starDS.Finish(Actions, Policy);
698 envDInfo.SetIdentifier(0,Loc);
699 envDInfo.AddTypeInfo(DeclaratorChunk::getPointer(starDS.getTypeQualifiers(), Loc,
700 starDS.getConstSpecLoc(),
701 starDS.getVolatileSpecLoc(),
702 starDS.getRestrictSpecLoc(),
703 starDS.getAtomicSpecLoc(),
704 starDS.getUnalignedSpecLoc()),
705 starDS.getAttributes(),
706 SourceLocation());
707 ExprVector ArgExprs2;
708 LHS = LookupNameAndBuildExpr(envII);
709 ArgExprs2.push_back(LHS.get());
710 LHS = Actions.ActOnParenListExpr(Loc, Loc, ArgExprs2);
711 Expr *envCastExpr = LHS.get();
712 TypeSourceInfo *castTInfo = Actions.GetTypeForDeclaratorCast(envDInfo, envCastExpr->getType());
713 LHS = Actions.MaybeConvertParenListExprToParenExpr(getCurScope(), envCastExpr);
714 envCastExpr = LHS.get();
715 LHS = Actions.BuildCStyleCastExpr(Loc, castTInfo, Loc, envCastExpr);
716 ArgExprs.push_back(LHS.get());
717 LHS = Actions.ActOnParenListExpr(Loc, Loc, ArgExprs);
718 LHS = LookupMemberAndBuildExpr(CreateIdentifierInfo(__CBC_STRUCT_POINTER_NAME, Loc),
719 LHS.get(), true);
720 Expr *ret_pCastExpr = LHS.get();
721 DeclarationName noValDeclName;
722 TypeSourceInfo *CurFuncTypesPointerTI = Actions.Context.CreateTypeSourceInfo(Actions.BuildPointerType(CurFuncResQT, Loc, noValDeclName));
723 LHS = Actions.BuildCStyleCastExpr(Loc, CurFuncTypesPointerTI, Loc, ret_pCastExpr);
724 LHS = Actions.ActOnUnaryOp(getCurScope(), Loc, tok::star, LHS.get());
725 ExprResult RHS;
726 RHS = LookupNameAndBuildExpr(retvalII);
727
728 retvalAssginmentExpr = Actions.ActOnBinOp(getCurScope(), Loc, tok::equal, LHS.get(), RHS.get());
729 innerR = Actions.ActOnExprStmt(retvalAssginmentExpr);
730 if(innerR.isUsable())
731 FnStmts.push_back(innerR.get());
732
733 ExprResult ljExpr,ljLHS;
734 ljExpr = IIToExpr(CreateIdentifierInfo("__builtin_longjmp", Loc), tok::l_paren);
735 ExprVector ljArgExprs;
736 DeclSpec ljDS(AttrFactory);
737 setTST(&ljDS, DeclSpec::TST_struct, structName);
738
739 Declarator ljD(ljDS, DeclaratorContext::TypeNameContext);
740 ljD.SetRangeEnd(Loc);
741 DeclSpec starDS2(AttrFactory);
742 starDS2.Finish(Actions, Policy);
743 ljD.ExtendWithDeclSpec(starDS2);
744 ljD.SetIdentifier(0, Loc);
745 ljD.AddTypeInfo(DeclaratorChunk::getPointer(ljDS.getTypeQualifiers(), Loc,
746 ljDS.getConstSpecLoc(),
747 ljDS.getVolatileSpecLoc(),
748 ljDS.getRestrictSpecLoc(),
749 ljDS.getAtomicSpecLoc(),
750 ljDS.getUnalignedSpecLoc()),
751 ljDS.getAttributes(),
752 SourceLocation());
753 ljLHS = LookupNameAndBuildExpr(envII);
754 Expr *ljCastExpr = ljLHS.get();
755 TypeSourceInfo *ljCastTInfo = Actions.GetTypeForDeclaratorCast(ljD, ljCastExpr->getType());
756 ljLHS = Actions.BuildCStyleCastExpr(Loc, ljCastTInfo, Loc, ljCastExpr);
757 ljLHS = Actions.ActOnParenExpr(Loc, Loc, ljLHS.get());
758 ljLHS = LookupMemberAndBuildExpr(envII, ljLHS.get(), true);
759 ljLHS = Actions.ActOnParenExpr(Loc, Loc, ljLHS.get());
760 ljArgExprs.push_back(ljLHS.get());
761 CommaLocs.push_back(Loc);
762 ljLHS = Actions.ActOnIntegerConstant(Loc, 1 /* return value for setjmp */);
763 ljArgExprs.push_back(ljLHS.get());
764 ljExpr = Actions.ActOnCallExpr(getCurScope(), ljExpr.get(), Loc, ljArgExprs, Loc, 0);
765 innerR = Actions.ActOnExprStmt(ljExpr);
766 if(innerR.isUsable())
767 FnStmts.push_back(innerR.get());
768 FnBody = Actions.ActOnCompoundStmt(Loc, Loc, FnStmts, false);
769 BodyScope.Exit();
770 TheDecl = Actions.ActOnFinishFunctionBody(BodyRes, FnBody.get());
771 returnDecl = Actions.ConvertDeclToDeclGroup(TheDecl);
772 (&Actions.getASTConsumer())->HandleTopLevelDecl(returnDecl.get());
773 Actions.CurScope = SavedScope;
774 Actions.CurContext = SavedContext;
775 Actions.FunctionScopes.push_back(SavedFSI);
776 }
777
778 /// IIToExpr - Create ExprResult from IdentifierInfo.
779 /// It is used when II is a not primary expression such as not primary types, a function's name, etc.
780 ExprResult Parser::IIToExpr(IdentifierInfo *II, tok::TokenKind Kind){
781 SourceLocation Loc = Tok.getLocation();
782 Token Next,IITok;
783 Next.setKind(Kind);
784 std::unique_ptr<ExternalSpace::StatementFilterCCC> CCCValidator(new ExternalSpace::StatementFilterCCC(Next));
785 CXXScopeSpec SS;
786 Sema::NameClassification Classification = Actions.ClassifyName(getCurScope(), SS, II, Loc, Next, false, std::move(CCCValidator));
787 IITok.startToken();
788 IITok.setLocation(Loc);
789 IITok.setIdentifierInfo(II);
790 IITok.setKind(tok::annot_primary_expr);
791 setExprAnnotation(IITok, Classification.getExpression());
792 IITok.setAnnotationEndLoc(Loc);
793 PP.AnnotateCachedTokens(IITok);
794 return getExprAnnotation(IITok);
795 }
796
797 /// CreateComplexStmtRet - Create return value for complex statements.
798 ///
799 /// ({ /* some statements */
800 /// return_value; )};
801 /// ^^^^^^^^^^^^^ Create it.
802 StmtResult Parser::CreateComplexStmtRet(IdentifierInfo *II, bool IsAddressOfOperand){
803 ExprResult ER;
804 if (IsAddressOfOperand) {
805 ER = LookupNameAndBuildExpr(II, true);
806 ER = Actions.ActOnUnaryOp(getCurScope(), Tok.getLocation(), tok::amp, ER.get());
807 }
808 else
809 ER = IIToExpr(II,tok::semi);
810 return Actions.ActOnExprStmt(ER);
811 }
812
813 /// CreateParam - Create paramator for functions.
814 ///
815 /// int funcname(int aua) {
816 /// ^^^^^^^ Create it.
817 ParmVarDecl* Parser::CreateParam(IdentifierInfo *II, int pointerNum, DeclSpec::TST T){
818 const PrintingPolicy &Policy = Actions.getASTContext().getPrintingPolicy();
819 SourceLocation Loc = Tok.getLocation();
820 DeclSpec DS(AttrFactory);
821 setTST(&DS, T);
822 Declarator ParamDeclarator(DS, DeclaratorContext::PrototypeContext);
823 ParamDeclarator.SetIdentifier(II, Loc);
824 for(int i = 0;i<pointerNum; i++){
825 DeclSpec pointerDS(AttrFactory);
826 pointerDS.Finish(Actions, Policy);
827 ParamDeclarator.AddTypeInfo(DeclaratorChunk::getPointer(pointerDS.getTypeQualifiers(), Loc,
828 pointerDS.getConstSpecLoc(),
829 pointerDS.getVolatileSpecLoc(),
830 pointerDS.getRestrictSpecLoc(),
831 pointerDS.getAtomicSpecLoc(),
832 pointerDS.getUnalignedSpecLoc()),
833 pointerDS.getAttributes(),SourceLocation());
834 }
835 ParmVarDecl *Param = dyn_cast<ParmVarDecl>(Actions.ActOnParamDeclarator(getCurScope(), ParamDeclarator));
836 return Param;
837
838 }
839
840 /// setTST - set TypeSpecifierType(TST) DeclSpec.
841 /// TST is specifiers the kind of type such as int, double, char, etc.
842 void Parser::setTST(DeclSpec *DS, DeclSpec::TST T, IdentifierInfo* Name, DeclSpec::TQ TQ){
843 const PrintingPolicy &Policy = Actions.getASTContext().getPrintingPolicy();
844 SourceLocation Loc = Tok.getLocation();
845 bool isInvalid = false;
846 const char *PrevSpec = 0;
847 unsigned DiagID = 0;
848 CXXScopeSpec SS;
849 DS->SetRangeStart(Loc);
850 DS->SetRangeEnd(Loc);
851 if (TQ != DeclSpec::TQ_unspecified) {
852 isInvalid = DS->SetTypeQual(DeclSpec::TQ_volatile, Loc, PrevSpec, DiagID,
853 getLangOpts());
854 }
855
856 if (T == DeclSpec::TST_struct) {
857 ParsedAttributesWithRange attrs(AttrFactory);
858 DeclResult TagOrTempResult = true;
859 bool Owned = false;
860 bool IsDependent = false;
861 MultiTemplateParamsArg TParams;
862 TagOrTempResult = Actions.ActOnTag(getCurScope(), T, Sema::TUK_Reference, Loc,
863 SS, Name, Loc, attrs.getList(), AS_none,
864 DS->getModulePrivateSpecLoc(),
865 TParams, Owned, IsDependent,
866 SourceLocation(), false,
867 clang::TypeResult(), false, false);
868 isInvalid = DS->SetTypeSpecType(T, Loc, Loc, PrevSpec, DiagID, TagOrTempResult.get(), Owned, Policy);
869 }
870 else if (T == DeclSpec::TST_typename) {
871 Token Next,TypeTok;
872 Next.setKind(tok::identifier);
873 std::unique_ptr<ExternalSpace::StatementFilterCCC> CCCValidator(new ExternalSpace::StatementFilterCCC(Next));
874 Sema::NameClassification Classification = Actions.ClassifyName(getCurScope(), SS, Name, Loc, Next, false, std::move(CCCValidator));
875 TypeTok.startToken();
876 TypeTok.setLocation(Loc);
877 TypeTok.setIdentifierInfo(Name);
878 TypeTok.setKind(tok::annot_typename);
879 setTypeAnnotation(TypeTok, Classification.getType());
880 TypeTok.setAnnotationEndLoc(Loc);
881 PP.AnnotateCachedTokens(TypeTok);
882 if (TypeTok.getAnnotationValue()) {
883 ParsedType PT = getTypeAnnotation(TypeTok);
884 isInvalid = DS->SetTypeSpecType(T, Loc, PrevSpec, DiagID, PT, Policy);
885 } else
886 DS->SetTypeSpecError();
887 }
888 else
889 isInvalid = DS->SetTypeSpecType(T, Loc, PrevSpec, DiagID, Policy);
890
891 DS->Finish(Actions, Policy);
892 if (isInvalid) {
893 assert(PrevSpec && "Method did not return previous specifier!");
894 assert(DiagID);
895 if (DiagID == diag::ext_duplicate_declspec)
896 Diag(Tok, DiagID)
897 << PrevSpec << FixItHint::CreateRemoval(Tok.getLocation());
898 else
899 Diag(Tok, DiagID) << PrevSpec;
900 }
901 }
902
903 /// CheckTheSjHeader - Check whether setjmp.h has been already included or not.
904 /// If not, include it.
905 void Parser::CheckTheSjHeader(){
906 SourceLocation Loc = Tok.getLocation();
907 LookupResult R(Actions, CreateIdentifierInfo("setjmp", Loc), Loc, Actions.LookupOrdinaryName, Actions.ForVisibleRedeclaration);
908 if (!Actions.LookupName(R, getCurScope())){ // look up the setjmp
909 if (PP.IncludeHeader(Tok, "setjmp.h"))
910 ConsumeToken();
911 }
912 }
913
914 /// isVoidFunction - Return true if current function return type is void.
915 bool Parser::isVoidFunction(){
916 return Actions.getCurFunctionDecl()->getReturnType().getTypePtr()->isVoidType();
917 }
918
919 /// ParseCbCGotoStatement
920 /// jump-statement:
921 /// [CbC] 'goto' codeSegment ';'
922 ///
923 StmtResult Parser::ParseCbCGotoStatement(ParsedAttributesWithRange &Attrs,StmtVector &Stmts) {
924 assert(Tok.is(tok::kw_goto) && "Not a goto stmt!");
925 ParseScope CompoundScope(this, Scope::DeclScope);
926 StmtVector CompoundedStmts;
927
928 SourceLocation gotoLoc = ConsumeToken(); // eat the 'goto'.
929 StmtResult gotoRes;
930 Token TokAfterGoto = Tok;
931 Stmtsp = &Stmts;
932
933 gotoRes = ParseStatementOrDeclaration(Stmts, ACK_Any);
934
935 if (gotoRes.get() == NULL)
936 return StmtError();
937 else if (gotoRes.get()->getStmtClass() != Stmt::CallExprClass) { // if it is not function call
938 unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error, "expected identifier or codesegment call");
939 Diag(TokAfterGoto, DiagID);
940 return StmtError();
941 }
942
943 assert((Attrs.empty() || gotoRes.isInvalid() || gotoRes.isUsable()) &&
944 "attributes on empty statement");
945 if (!(Attrs.empty() || gotoRes.isInvalid()))
946 gotoRes = Actions.ProcessStmtAttributes(gotoRes.get(), Attrs.getList(), Attrs.Range);
947 if (gotoRes.isUsable())
948 CompoundedStmts.push_back(gotoRes.get());
949
950 // add return; after goto codesegment();
951 if (Actions.getCurFunctionDecl()->getReturnType().getTypePtr()->is__CodeType()) {
952 ExprResult retExpr;
953 StmtResult retRes;
954 retRes = Actions.ActOnReturnStmt(gotoLoc, retExpr.get(), getCurScope());
955 if (retRes.isUsable())
956 CompoundedStmts.push_back(retRes.get());
957 }
958 return Actions.ActOnCompoundStmt(gotoLoc, Tok.getLocation(), CompoundedStmts, false);
959 }
960
961 /// SearchCodeSegmentDeclaration - Read tokens until we get to the specified code segment declaration.
962 /// If we can't find it , return false;
963 bool Parser::SearchCodeSegmentDeclaration(std::string Name){
964 while(SkipAnyUntil(tok::kw___code, StopBeforeMatch)){
965 if(NextToken().is(tok::identifier) && NextToken().getIdentifierInfo()->getName().str() == Name)
966 return true;
967 ConsumeToken();
968 }
969 return false;
970 }
971
972 bool Parser::NeedPrototypeDeclaration(Token IITok){
973 LookupResult LR(Actions, IITok.getIdentifierInfo(), IITok.getLocation(), Actions.LookupOrdinaryName);
974 CXXScopeSpec SS;
975 Actions.LookupParsedName(LR, getCurScope(), &SS, !(Actions.getCurMethodDecl()));
976
977 return (LR.getResultKind() == LookupResult::NotFound);
978 }
979
980 /// CreatePrototypeDeclaration - Create prototype declaration by it's definition.
981 void Parser::CreatePrototypeDeclaration(){
982 // move to the top level scope
983 Scope *SavedScope = getCurScope();
984 DeclContext *SavedContext = Actions.CurContext;
985 sema::FunctionScopeInfo *SavedFSI = Actions.FunctionScopes.pop_back_val();
986 Actions.CurContext = static_cast<DeclContext *>(Actions.Context.getTranslationUnitDecl());
987 Scope *TopScope = getCurScope();
988 while(TopScope->getParent() != NULL)
989 TopScope = TopScope->getParent();
990 Actions.CurScope = TopScope;
991
992 Token Next = NextToken();
993 Token CachedTokens[3] = {Next, PP.LookAhead(1)};
994 Token SavedToken = Tok;
995 Token IITok = Tok.is(tok::identifier) ? Tok : Next;
996 PP.ClearCache();
997 PP.ProtoParsing = true;
998 ProtoParsing = true;
999
1000 const DirectoryLookup *CurDir = nullptr;
1001 FileID FID = PP.getSourceManager().createFileID(PP.getCurrentFileLexer()->getFileEntry(), IITok.getLocation(), SrcMgr::C_User);
1002 PP.EnterSourceFile(FID,CurDir,IITok.getLocation());
1003 ConsumeToken();
1004
1005 if(SearchCodeSegmentDeclaration(IITok.getIdentifierInfo()->getName().str())){
1006 DeclGroupPtrTy ProtoDecl;
1007 ParseTopLevelDecl(ProtoDecl);
1008 // add declaration to AST.
1009 if(ProtoDecl)
1010 (&Actions.getASTConsumer())->HandleTopLevelDecl(ProtoDecl.get());
1011 // File Closing
1012 Token T;
1013 PP.HandleEndOfFile(T, false);
1014
1015 // recover tokens.
1016 Tok = SavedToken;
1017 PP.RestoreTokens(CachedTokens, 2);
1018
1019 }
1020 else {
1021 // recover tokens.
1022 CachedTokens[2] = Tok;
1023 Tok = SavedToken;
1024 PP.RestoreTokens(CachedTokens, 3);
1025 }
1026
1027 // move to the previous scope.
1028 Actions.CurScope = SavedScope;
1029 Actions.CurContext = SavedContext;
1030 Actions.FunctionScopes.push_back(SavedFSI);
1031
1032 ProtoParsing = false;
1033 PP.ProtoParsing = false;
1034 }
1035
1036 static bool HasFlagsSet(Parser::SkipUntilFlags L, Parser::SkipUntilFlags R) {
1037 return (static_cast<unsigned>(L) & static_cast<unsigned>(R)) != 0;
1038 }
1039
1040 bool Parser::SkipAnyUntil(tok::TokenKind T, SkipUntilFlags Flags){
1041 const PreprocessorLexer *L = PP.getCurrentFileLexer();
1042 while(1){
1043 if(Tok.is(T)){
1044 if (HasFlagsSet(Flags, StopBeforeMatch)) {
1045 // Noop, don't consume the token.
1046 } else {
1047 ConsumeAnyToken();
1048 }
1049 return true;
1050 }
1051 else if(PP.getCurrentFileLexer() != L){
1052 return false;
1053 }
1054
1055 ConsumeAnyToken();
1056 }
1057 }
1058
1059 #endif