Mercurial > hg > CbC > CbC_llvm
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 |