void C2Sema::ActOnImport(const char* moduleName_, SourceLocation loc, Token& aliasTok, bool isLocal) { #ifdef SEMA_DEBUG std::cerr << COL_SEMA"SEMA: import " << moduleName_ << " at "; loc.dump(SourceMgr); std::cerr << ANSI_NORMAL"\n"; #endif std::string moduleName = moduleName_; // check if importing own module if (ast.getModuleName() == moduleName) { Diag(loc, diag::err_import_own_module) << moduleName_; return; } // check for duplicate import of module const ImportDecl* old = findModule(moduleName); if (old) { Diag(loc, diag::err_duplicate_import) << moduleName; Diag(old->getLocation(), diag::note_previous_import); return; } std::string name = moduleName; if (aliasTok.is(tok::identifier)) { name = aliasTok.getIdentifierInfo()->getNameStart(); // check if same as normal module name if (name == moduleName) { Diag(aliasTok.getLocation(), diag::err_alias_same_as_module); return; } } ImportDecl* U = new ImportDecl(name, loc, isLocal, moduleName, aliasTok.getLocation()); U->setType(typeContext.getModuleType(U)); ast.addImport(U); addSymbol(U); }
void C2Sema::ActOnUse(const char* name, SourceLocation loc, Token& aliasTok, bool isLocal) { #ifdef SEMA_DEBUG std::cerr << COL_SEMA"SEMA: use " << name << " at "; loc.dump(SourceMgr); std::cerr << ANSI_NORMAL"\n"; #endif // check if use-ing own package if (ast.getPkgName() == name) { Diag(loc, diag::err_use_own_package) << name; return; } // check for duplicate use const Decl* old = findUse(name); if (old) { Diag(loc, diag::err_duplicate_use) << name; Diag(old->getLocation(), diag::note_previous_use); return; } const char* aliasName = ""; if (aliasTok.is(tok::identifier)) { aliasName = aliasTok.getIdentifierInfo()->getNameStart(); // check if same as normal package name if (strcmp(name, aliasName) == 0) { Diag(aliasTok.getLocation(), diag::err_alias_same_as_package); return; } const UseDecl* old = findAlias(aliasName); if (old) { Diag(aliasTok.getLocation(), diag::err_duplicate_use) << aliasName; Diag(old->getAliasLocation(), diag::note_previous_use); return; } } ast.addDecl(new UseDecl(name, loc, isLocal, aliasName, aliasTok.getLocation())); }
void C2Sema::ActOnModule(const char* name, SourceLocation loc) { #ifdef SEMA_DEBUG std::cerr << COL_SEMA << "SEMA: module " << name << " at "; loc.dump(SourceMgr); std::cerr << ANSI_NORMAL"\n"; #endif if (name[0] == '_' && name[1] == '_') { Diag(loc, diag::err_invalid_symbol_name) << name; return; } if (!islower(name[0]) && !ast.isInterface()) { Diag(loc, diag::err_module_casing); return; } if (strcmp(name, "c2") == 0) { Diag(loc, diag::err_module_c2); return; } if (strcmp(name, "main") == 0) { Diag(loc, diag::err_module_invalid_name) << name; return; } ast.setName(name, loc); ImportDecl* U = new ImportDecl(name, loc, true, name, SourceLocation()); U->setType(typeContext.getModuleType(U)); U->setUsed(); ast.addImport(U); addSymbol(U); }
C2::StmtResult C2Sema::ActOnLabelStmt(const char* name, SourceLocation loc, Stmt* subStmt) { #ifdef SEMA_DEBUG std::cerr << COL_SEMA"SEMA: label statement at "; loc.dump(SourceMgr); std::cerr << ANSI_NORMAL"\n"; #endif return StmtResult(new LabelStmt(name, loc, subStmt)); }
C2::StmtResult C2Sema::ActOnReturnStmt(SourceLocation loc, Expr* value) { #ifdef SEMA_DEBUG std::cerr << COL_SEMA"SEMA: return at "; loc.dump(SourceMgr); std::cerr << ANSI_NORMAL"\n"; #endif return StmtResult(new ReturnStmt(loc, value)); }
void C2Sema::ActOnArrayValue(const char* name, SourceLocation loc, Expr* Value) { #ifdef SEMA_DEBUG std::cerr << COL_SEMA"SEMA: arrayvalue at "; loc.dump(SourceMgr); std::cerr << ANSI_NORMAL"\n"; #endif ast.addArrayValue(new ArrayValueDecl(name, loc, Value)); }
C2::StmtResult C2Sema::ActOnCaseStmt(SourceLocation loc, Expr* Cond, StmtList& stmts) { #ifdef SEMA_DEBUG std::cerr << COL_SEMA"SEMA: case statement at "; loc.dump(SourceMgr); std::cerr << ANSI_NORMAL"\n"; #endif return StmtResult(new CaseStmt(loc, Cond, stmts)); }
C2::ExprResult C2Sema::ActOnNil(SourceLocation L) { #ifdef SEMA_DEBUG std::cerr << COL_SEMA"SEMA: nil expr at "; L.dump(SourceMgr); std::cerr << ANSI_NORMAL"\n"; #endif return ExprResult(new NilExpr(L)); }
C2::ExprResult C2Sema::ActOnInitList(SourceLocation left_, SourceLocation right_, ExprList& vals) { #ifdef SEMA_DEBUG std::cerr << COL_SEMA"SEMA: initlist at "; left_.dump(SourceMgr); std::cerr << ANSI_NORMAL"\n"; #endif return ExprResult(new InitListExpr(left_, right_, vals)); }
C2::StmtResult C2Sema::ActOnCompoundStmt(SourceLocation L, SourceLocation R, StmtList& stmts) { #ifdef SEMA_DEBUG std::cerr << COL_SEMA"SEMA: compound statement at "; L.dump(SourceMgr); std::cerr << ANSI_NORMAL"\n"; #endif return StmtResult(new CompoundStmt(L, R, stmts)); }
C2::ExprResult C2Sema::ActOnFieldDesignatorExpr(SourceLocation loc, IdentifierInfo* field, ExprResult InitValue) { #ifdef SEMA_DEBUG std::cerr << COL_SEMA"SEMA: FieldDesignatorExpr at "; loc.dump(SourceMgr); std::cerr << ANSI_NORMAL"\n"; #endif return ExprResult(new DesignatedInitExpr(loc, field->getNameStart(), InitValue.get())); }
C2::StmtResult C2Sema::ActOnGotoStmt(const char* name, SourceLocation GotoLoc, SourceLocation LabelLoc) { #ifdef SEMA_DEBUG std::cerr << COL_SEMA"SEMA: goto statement at "; GotoLoc.dump(SourceMgr); std::cerr << ANSI_NORMAL"\n"; #endif return StmtResult(new GotoStmt(name, GotoLoc, LabelLoc)); }
C2::StmtResult C2Sema::ActOnDefaultStmt(SourceLocation loc, StmtList& stmts) { #ifdef SEMA_DEBUG std::cerr << COL_SEMA"SEMA: default statement at "; loc.dump(SourceMgr); std::cerr << ANSI_NORMAL"\n"; #endif return StmtResult(new DefaultStmt(loc, stmts)); }
C2::StmtResult C2Sema::ActOnContinueStmt(SourceLocation loc) { #ifdef SEMA_DEBUG std::cerr << COL_SEMA"SEMA: continue statement at "; loc.dump(SourceMgr); std::cerr << ANSI_NORMAL"\n"; #endif return StmtResult(new ContinueStmt(loc)); }
C2::StmtResult C2Sema::ActOnSwitchStmt(SourceLocation loc, Stmt* Cond, StmtList& cases) { #ifdef SEMA_DEBUG std::cerr << COL_SEMA"SEMA: switch statement at "; loc.dump(SourceMgr); std::cerr << ANSI_NORMAL"\n"; #endif return StmtResult(new SwitchStmt(loc, Cond, cases)); }
C2::StmtResult C2Sema::ActOnForStmt(SourceLocation loc, Stmt* Init, Expr* Cond, Expr* Incr, Stmt* Body) { #ifdef SEMA_DEBUG std::cerr << COL_SEMA"SEMA: for statement at "; loc.dump(SourceMgr); std::cerr << ANSI_NORMAL"\n"; #endif return StmtResult(new ForStmt(loc, Init, Cond, Incr, Body)); }
C2::StmtResult C2Sema::ActOnDoStmt(SourceLocation loc, ExprResult Cond, StmtResult Then) { #ifdef SEMA_DEBUG std::cerr << COL_SEMA"SEMA: do statement at "; loc.dump(SourceMgr); std::cerr << ANSI_NORMAL"\n"; #endif return StmtResult(new DoStmt(loc, Cond.get(), Then.get())); }
C2::ExprResult C2Sema::ActOnParenExpr(SourceLocation L, SourceLocation R, Expr* E) { assert(E && "missing expr"); #ifdef SEMA_DEBUG std::cerr << COL_SEMA"SEMA: paren expr at "; L.dump(SourceMgr); std::cerr << ANSI_NORMAL"\n"; #endif return ExprResult(new ParenExpr(L, R, E)); }
C2::ExprResult C2Sema::ActOnIdExpression(IdentifierInfo& symII, SourceLocation symLoc) { std::string id(symII.getNameStart(), symII.getLength()); #ifdef SEMA_DEBUG std::cerr << COL_SEMA"SEMA: identifier " << id << " at "; symLoc.dump(SourceMgr); std::cerr << ANSI_NORMAL"\n"; #endif return ExprResult(new IdentifierExpr(symLoc, id)); }
// see clang, some GCC extension allows LHS to be null (C2 doesn't?) C2::ExprResult C2Sema::ActOnConditionalOp(SourceLocation QuestionLoc, SourceLocation ColonLoc, Expr* CondExpr, Expr* LHSExpr, Expr* RHSExpr) { #ifdef SEMA_DEBUG std::cerr << COL_SEMA"SEMA: CondOp at "; QuestionLoc.dump(SourceMgr); std::cerr << ANSI_NORMAL"\n"; #endif return ExprResult(new ConditionalOperator(QuestionLoc, ColonLoc, CondExpr, LHSExpr, RHSExpr)); }
C2::StmtResult C2Sema::ActOnIfStmt(SourceLocation ifLoc, Stmt* condition, StmtResult thenStmt, SourceLocation elseLoc, StmtResult elseStmt) { #ifdef SEMA_DEBUG std::cerr << COL_SEMA"SEMA: if statement at "; ifLoc.dump(SourceMgr); std::cerr << ANSI_NORMAL"\n"; #endif return StmtResult(new IfStmt(ifLoc, condition, thenStmt.get(), elseLoc, elseStmt.get())); }
C2::ExprResult C2Sema::ActOnBitOffset(SourceLocation colLoc, Expr* LHS, Expr* RHS) { assert(LHS); assert(RHS); #ifdef SEMA_DEBUG std::cerr << COL_SEMA"SEMA: bitoffset at "; colLoc.dump(SourceMgr); std::cerr << ANSI_NORMAL"\n"; #endif return ExprResult(new BitOffsetExpr(LHS, RHS, colLoc)); }
C2::ExprResult C2Sema::ActOnArraySubScriptExpr(SourceLocation RLoc, Expr* Base, Expr* Idx) { assert(Base); assert(Idx); #ifdef SEMA_DEBUG std::cerr << COL_SEMA << "SEMA: array subscript at "; RLoc.dump(SourceMgr); std::cerr << ANSI_NORMAL"\n"; #endif return ExprResult(new ArraySubscriptExpr(RLoc, Base, Idx)); }
C2::ExprResult C2Sema::ActOnUnaryOp(SourceLocation OpLoc, tok::TokenKind Kind, Expr* Input) { assert(Input); #ifdef SEMA_DEBUG std::cerr << COL_SEMA << "SEMA: unary op at "; OpLoc.dump(SourceMgr); std::cerr << ANSI_NORMAL"\n"; #endif UnaryOperatorKind Opc = ConvertTokenKindToUnaryOpcode(Kind); return ExprResult(new UnaryOperator(OpLoc, Opc, Input)); }
C2::ExprResult C2Sema::ActOnBuiltinExpression(SourceLocation Loc, Expr* expr, bool isSizeof) { assert(expr); #ifdef SEMA_DEBUG const char* fname = (isSizeof ? "sizeof" : "elemsof"); std::cerr << COL_SEMA << "SEMA: " << fname << " at "; Loc.dump(SourceMgr); std::cerr << ANSI_NORMAL"\n"; #endif return ExprResult(new BuiltinExpr(Loc, expr, isSizeof)); }
C2::ExprResult C2Sema::ActOnCharacterConstant(SourceLocation Loc, const std::string& value) { #ifdef SEMA_DEBUG std::cerr << COL_SEMA"SEMA: char constant at "; Loc.dump(SourceMgr); std::cerr << ANSI_NORMAL"\n"; #endif // TODO parse value (\0, octal, \0x, etc) (see clang::CharLiteralParser) const char* str = value.c_str(); assert(str[0] == '\'' && str[2] == '\'' && "char constant parsing not supported yet"); unsigned cvalue = str[1]; return ExprResult(new CharacterLiteral(Loc, cvalue)); }
void C2Sema::ActOnStructVar(StructTypeDecl* S, const char* name, SourceLocation loc, Expr* type, Expr* InitValue, bool is_public) { #ifdef SEMA_DEBUG std::cerr << COL_SEMA << "SEMA: struct var " << name << " at "; loc.dump(SourceMgr); std::cerr << ANSI_NORMAL"\n"; #endif TypeExpr* typeExpr = cast<TypeExpr>(type); if (typeExpr->hasLocalQualifier()) { Diag(loc, diag::err_invalid_local_structmember) << (S->isStruct() ? 0 : 1); } VarDecl* V = createVarDecl(VARDECL_MEMBER, name, loc, typeExpr, InitValue, is_public); ActOnStructMember(S, V); }
C2::DeclResult C2Sema::ActOnStructVar(const char* name, SourceLocation loc, Expr* type, Expr* InitValue, bool is_public) { #ifdef SEMA_DEBUG std::cerr << COL_SEMA"SEMA: struct var " << name << " at "; loc.dump(SourceMgr); std::cerr << ANSI_NORMAL"\n"; #endif TypeExpr* typeExpr = cast<TypeExpr>(type); if (typeExpr->hasLocalQualifier()) { //Diag(loc, diag::err_invalid_local_structmember); #warning "TODO add diag msg to clang" } VarDecl* V = createVarDecl(name, loc, typeExpr, InitValue, is_public); return DeclResult(V); }
C2::ExprResult C2Sema::ActOnBinOp(SourceLocation opLoc, tok::TokenKind Kind, Expr* LHS, Expr* RHS) { assert(LHS); assert(RHS); #ifdef SEMA_DEBUG std::cerr << COL_SEMA"SEMA: BinOp " << tok::getTokenSimpleSpelling(Kind) << " at "; opLoc.dump(SourceMgr); std::cerr << ANSI_NORMAL"\n"; #endif clang::BinaryOperatorKind Opc = ConvertTokenKindToBinaryOpcode(Kind); // Emit warnings for tricky precedence issues, e.g. "bitfield & 0x4 == 0" //DiagnoseBinOpPrecedence(*this, Opc, TokLoc, LHSExpr, RHSExpr); return ExprResult(new BinaryOperator(LHS, RHS, Opc, opLoc)); }
void C2Sema::ActOnPackage(const char* name, SourceLocation loc) { #ifdef SEMA_DEBUG std::cerr << COL_SEMA"SEMA: package " << name << " at "; loc.dump(SourceMgr); std::cerr << ANSI_NORMAL"\n"; #endif if (name[0] == '_' && name[1] == '_') { Diag(loc, diag::err_invalid_symbol_name) << name; return; } if (strcmp(name, "c2") == 0) { Diag(loc, diag::err_package_c2); return; } ast.setName(name, loc); }