00001
00002
00003
00004
00005
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
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 }
00338
00339 namespace llvm {
00340
00341
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
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
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 }
00425
00426
00427 #endif