This machine mirrors various open-source projects.
20 Gbit/s uplink.
If there are any issues or you want another project mirrored, please contact
mirror-service -=AT=- netcologne DOT de !
00001 //===-- ast/SubroutineCall.h ---------------------------------- -*- C++ -*-===// 00002 // 00003 // This file is distributed under the MIT license. See LICENSE.txt for details. 00004 // 00005 // Copyright (C) 2009, Stephen Wilson 00006 // 00007 //===----------------------------------------------------------------------===// 00008 00009 //===----------------------------------------------------------------------===// 00013 //===----------------------------------------------------------------------===// 00014 00015 #ifndef COMMA_AST_SUBROUTINECALL_HDR_GUARD 00016 #define COMMA_AST_SUBROUTINECALL_HDR_GUARD 00017 00018 #include "comma/ast/AstBase.h" 00019 #include "comma/ast/SubroutineRef.h" 00020 00021 namespace comma { 00022 00028 class SubroutineCall { 00029 00030 public: 00040 SubroutineCall(SubroutineRef *connective, 00041 Expr **positionalArgs, unsigned numPositional, 00042 KeywordSelector **keyedArgs, unsigned numKeys); 00043 00046 SubroutineCall(SubroutineDecl *connective, 00047 Expr **positionalArgs, unsigned numPositional, 00048 KeywordSelector **keyedArgs, unsigned numKeys); 00049 00050 virtual ~SubroutineCall(); 00051 00053 bool isaFunctionCall() const; 00054 00056 bool isaProcedureCall() const; 00057 00059 bool denotesOperator() const; 00060 00062 00063 FunctionCallExpr *asFunctionCall(); 00064 const FunctionCallExpr *asFunctionCall() const; 00066 00068 00069 ProcedureCallStmt *asProcedureCall(); 00070 const ProcedureCallStmt *asProcedureCall() const; 00072 00074 virtual Location getLocation() const = 0; 00075 00077 bool isAmbiguous() const { 00078 return connective->isOverloaded() || connective->empty(); 00079 } 00080 00082 bool isUnambiguous() const { return !isAmbiguous(); } 00083 00089 bool isPrimitive() const { 00090 return isUnambiguous() && getConnective()->isPrimitive(); 00091 } 00092 00094 bool isAttributeCall() const; 00095 00102 00103 00109 bool isLocalCall() const; 00110 00115 bool isDirectCall() const; 00116 00121 bool isAbstractCall() const; 00122 00127 bool isForeignCall() const; 00129 00146 virtual void resolveConnective(SubroutineDecl *connective); 00147 00150 unsigned getNumArgs() const { return numPositional + numKeys; } 00151 00153 unsigned getNumPositionalArgs() const { return numPositional; } 00154 00156 unsigned getNumKeyedArgs() const { return numKeys; } 00157 00159 bool containsConnective(SubroutineType *srTy) const { 00160 return connective->contains(srTy); 00161 } 00162 00164 unsigned numConnectives() const { return connective->numDeclarations(); } 00165 00167 00168 const SubroutineDecl *getConnective(unsigned i) const { 00169 return connective->getDeclaration(i); 00170 } 00171 SubroutineDecl *getConnective(unsigned i) { 00172 return connective->getDeclaration(i); 00173 } 00175 00177 00178 00179 00180 SubroutineDecl *getConnective() { 00181 assert(isUnambiguous() && 00182 "No unique connective associated with this call!"); 00183 return connective->getDeclaration(0); 00184 } 00185 00186 const SubroutineDecl *getConnective() const { 00187 assert(isUnambiguous() && 00188 "No unique connective associated with this call!"); 00189 return connective->getDeclaration(0); 00190 } 00192 00194 00195 00196 typedef SubroutineRef::iterator connective_iterator; 00197 connective_iterator begin_connectives() { return connective->begin(); } 00198 connective_iterator end_connectives() { return connective->end(); } 00199 00200 typedef SubroutineRef::const_iterator const_connective_iterator; 00201 const_connective_iterator begin_connectives() const { 00202 return connective->begin(); 00203 } 00204 const_connective_iterator end_connectives() const { 00205 return connective->end(); 00206 } 00208 00221 00222 typedef Expr **arg_iterator; 00223 arg_iterator begin_arguments() { 00224 assert(isUnambiguous() && 00225 "Cannot iterate over the arguments of an ambiguous call expr!"); 00226 return arguments ? &arguments[0] : 0; 00227 } 00228 arg_iterator end_arguments() { 00229 assert(isUnambiguous() && 00230 "Cannot iterate over the arguments of an ambiguous call expr!"); 00231 return arguments ? &arguments[getNumArgs()] : 0; 00232 } 00233 00234 typedef const Expr *const *const_arg_iterator; 00235 const_arg_iterator begin_arguments() const { 00236 assert(isUnambiguous() && 00237 "Cannot iterate over the arguments of an ambiguous call expr!"); 00238 return arguments ? &arguments[0] : 0; 00239 } 00240 const_arg_iterator end_arguments() const { 00241 assert(isUnambiguous() && 00242 "Cannot iterate over the arguments of an ambiguous call expr!"); 00243 return arguments ? &arguments[getNumArgs()] : 0; 00244 } 00246 00253 00254 arg_iterator begin_positional() { 00255 return numPositional ? &arguments[0] : 0; 00256 } 00257 arg_iterator end_positional() { 00258 return numPositional ? &arguments[numPositional] : 0; 00259 } 00260 00261 const_arg_iterator begin_positional() const { 00262 return numPositional ? &arguments[0] : 0; 00263 } 00264 const_arg_iterator end_positional() const { 00265 return numPositional ? &arguments[numPositional] : 0; 00266 } 00268 00276 00277 typedef KeywordSelector **key_iterator; 00278 key_iterator begin_keys() { return numKeys ? &keyedArgs[0] : 0; } 00279 key_iterator end_keys() { return numKeys ? &keyedArgs[numKeys] : 0; } 00280 00281 typedef KeywordSelector *const *const_key_iterator; 00282 const_key_iterator begin_keys() const { 00283 return numKeys ? &keyedArgs[0] : 0; 00284 } 00285 const_key_iterator end_keys() const { 00286 return numKeys ? &keyedArgs[numKeys] : 0; 00287 } 00289 00291 00292 void setArgument(arg_iterator I, Expr *expr); 00293 void setArgument(key_iterator I, Expr *expr); 00295 00297 Ast *asAst(); 00298 const Ast *asAst() const; 00299 00300 // Support isa and dyn_cast. 00301 static bool classof(const Ast *node) { 00302 Ast::AstKind kind = node->getKind(); 00303 return (kind == Ast::AST_FunctionCallExpr || 00304 kind == Ast::AST_ProcedureCallStmt); 00305 } 00306 static bool classof(const FunctionCallExpr *node) { return true; } 00307 static bool classof(const ProcedureCallStmt *node) { return true; } 00308 00309 protected: 00310 SubroutineRef *connective; 00311 Expr **arguments; 00312 KeywordSelector **keyedArgs; 00313 unsigned numPositional; 00314 unsigned numKeys; 00315 00318 bool isCompatible(SubroutineDecl *decl) const; 00319 00322 int argExprIndex(Expr *expr) const; 00323 00326 int keyExprIndex(Expr *expr) const; 00327 00328 private: 00330 void initializeArguments(Expr **posArgs, unsigned numPos, 00331 KeywordSelector **keyArgs, unsigned numKeys); 00332 00334 void propagateKeyedArguments(); 00335 }; 00336 00337 } // end comma namespace. 00338 00339 namespace llvm { 00340 00341 // Specialize isa_impl_wrap to test if a SubroutineCall is a specific Ast node. 00342 template<class To> 00343 struct isa_impl_wrap<To, 00344 const comma::SubroutineCall, const comma::SubroutineCall> { 00345 static bool doit(const comma::SubroutineCall &val) { 00346 return To::classof(val.asAst()); 00347 } 00348 }; 00349 00350 template<class To> 00351 struct isa_impl_wrap<To, comma::SubroutineCall, comma::SubroutineCall> 00352 : public isa_impl_wrap<To, 00353 const comma::SubroutineCall, 00354 const comma::SubroutineCall> { }; 00355 00356 // Ast to SubroutineCall conversions. 00357 template<class From> 00358 struct cast_convert_val<comma::SubroutineCall, From, From> { 00359 static comma::SubroutineCall &doit(const From &val) { 00360 const From *ptr = &val; 00361 return (dyn_cast<comma::FunctionCallExpr>(ptr) || 00362 dyn_cast<comma::ProcedureCallStmt>(ptr)); 00363 } 00364 }; 00365 00366 template<class From> 00367 struct cast_convert_val<comma::SubroutineCall, From*, From*> { 00368 static comma::SubroutineCall *doit(const From *val) { 00369 return (dyn_cast<comma::FunctionCallExpr>(val) || 00370 dyn_cast<comma::ProcedureCallStmt>(val)); 00371 } 00372 }; 00373 00374 template<class From> 00375 struct cast_convert_val<const comma::SubroutineCall, From, From> { 00376 static const comma::SubroutineCall &doit(const From &val) { 00377 const From *ptr = &val; 00378 return (dyn_cast<comma::FunctionCallExpr>(ptr) || 00379 dyn_cast<comma::ProcedureCallStmt>(ptr)); 00380 } 00381 }; 00382 00383 template<class From> 00384 struct cast_convert_val<const comma::SubroutineCall, From*, From*> { 00385 static const comma::SubroutineCall *doit(const From *val) { 00386 return (dyn_cast<comma::FunctionCallExpr>(val) || 00387 dyn_cast<comma::ProcedureCallStmt>(val)); 00388 } 00389 }; 00390 00391 // SubroutineCall to Ast conversions. 00392 template<class To> 00393 struct cast_convert_val<To, 00394 const comma::SubroutineCall, 00395 const comma::SubroutineCall> { 00396 static To &doit(const comma::SubroutineCall &val) { 00397 return *reinterpret_cast<To*>( 00398 const_cast<comma::Ast*>(val.asAst())); 00399 } 00400 }; 00401 00402 template<class To> 00403 struct cast_convert_val<To, comma::SubroutineCall, comma::SubroutineCall> 00404 : public cast_convert_val<To, 00405 const comma::SubroutineCall, 00406 const comma::SubroutineCall> { }; 00407 00408 template<class To> 00409 struct cast_convert_val<To, 00410 const comma::SubroutineCall*, 00411 const comma::SubroutineCall*> { 00412 static To *doit(const comma::SubroutineCall *val) { 00413 return reinterpret_cast<To*>( 00414 const_cast<comma::Ast*>(val->asAst())); 00415 } 00416 }; 00417 00418 template<class To> 00419 struct cast_convert_val<To, comma::SubroutineCall*, comma::SubroutineCall*> 00420 : public cast_convert_val<To, 00421 const comma::SubroutineCall*, 00422 const comma::SubroutineCall*> { }; 00423 00424 } // end llvm namespace; 00425 00426 00427 #endif