Mercurial > hg > CbC > CbC_llvm
changeset 35:503e14e069e4
update to LLVM 3.5
line wrap: on
line diff
--- a/include/llvm/CodeGen/Passes.h Thu Dec 12 15:22:36 2013 +0900 +++ b/include/llvm/CodeGen/Passes.h Thu Dec 12 23:38:21 2013 +0900 @@ -141,6 +141,9 @@ void setInitialized() { Initialized = true; } CodeGenOpt::Level getOptLevel() const { return TM->getOptLevel(); } +#ifndef noCbC + unsigned hasCodeSegment() { return TM->Options.HasCodeSegment; } +#endif /// setStartStopPasses - Set the StartAfter and StopAfter passes to allow /// running only a portion of the normal code-gen pass sequence. If the
--- a/include/llvm/IR/IRBuilder.h Thu Dec 12 15:22:36 2013 +0900 +++ b/include/llvm/IR/IRBuilder.h Thu Dec 12 23:38:21 2013 +0900 @@ -331,6 +331,12 @@ return Type::getVoidTy(Context); } +#ifndef noCbC + Type *get__CodeTy() { + return Type::get__CodeTy(Context); + } +#endif + /// \brief Fetch the type representing a pointer to an 8-bit integer value. PointerType *getInt8PtrTy(unsigned AddrSpace = 0) { return Type::getInt8PtrTy(Context, AddrSpace);
--- a/include/llvm/IR/Type.h Thu Dec 12 15:22:36 2013 +0900 +++ b/include/llvm/IR/Type.h Thu Dec 12 23:38:21 2013 +0900 @@ -72,6 +72,9 @@ ArrayTyID, ///< 13: Arrays PointerTyID, ///< 14: Pointers VectorTyID ///< 15: SIMD 'packed' format, or other vector type +#ifndef noCbC + ,__CodeTyID +#endif }; private: @@ -134,7 +137,16 @@ TypeID getTypeID() const { return (TypeID)(IDAndSubclassData & 0xFF); } /// isVoidTy - Return true if this is 'void'. +#ifndef noCbC + bool isVoidTy() const { return (getTypeID() == VoidTyID || getTypeID() == __CodeTyID); } +#else bool isVoidTy() const { return getTypeID() == VoidTyID; } +#endif + +#ifndef noCbC + /// is__CodeTy - Return true if this is '__code'. + bool is__CodeTy() const { return getTypeID() == __CodeTyID; } +#endif /// isHalfTy - Return true if this is 'half', a 16-bit IEEE fp type. bool isHalfTy() const { return getTypeID() == HalfTyID; } @@ -240,7 +252,11 @@ /// is a valid type for a Value. /// bool isFirstClassType() const { +#ifndef noCbC + return getTypeID() != FunctionTyID && getTypeID() != VoidTyID && getTypeID() != __CodeTyID; +#else return getTypeID() != FunctionTyID && getTypeID() != VoidTyID; +#endif } /// isSingleValueType - Return true if the type is a valid type for a @@ -393,6 +409,10 @@ static IntegerType *getInt32Ty(LLVMContext &C); static IntegerType *getInt64Ty(LLVMContext &C); +#ifndef noCbC + static Type *get__CodeTy(LLVMContext &C); // for CbC project +#endif + //===--------------------------------------------------------------------===// // Convenience methods for getting pointer types with one of the above builtin // types as pointee.
--- a/include/llvm/LinkAllPasses.h Thu Dec 12 15:22:36 2013 +0900 +++ b/include/llvm/LinkAllPasses.h Thu Dec 12 23:38:21 2013 +0900 @@ -125,7 +125,11 @@ (void) llvm::createStripNonDebugSymbolsPass(); (void) llvm::createStripDeadDebugInfoPass(); (void) llvm::createStripDeadPrototypesPass(); +#ifndef noCbC + (void) llvm::createTailCallEliminationPass(false); +#else (void) llvm::createTailCallEliminationPass(); +#endif (void) llvm::createJumpThreadingPass(); (void) llvm::createUnifyFunctionExitNodesPass(); (void) llvm::createInstCountPass();
--- a/include/llvm/Target/TargetOptions.h Thu Dec 12 15:22:36 2013 +0900 +++ b/include/llvm/Target/TargetOptions.h Thu Dec 12 23:38:21 2013 +0900 @@ -189,6 +189,9 @@ /// via the llvm.fma.* intrinsic) will always be honored, regardless of /// the value of this option. FPOpFusion::FPOpFusionMode AllowFPOpFusion; +#ifndef noCbC + unsigned HasCodeSegment : 1; +#endif }; // Comparison operators:
--- a/include/llvm/Transforms/Scalar.h Thu Dec 12 15:22:36 2013 +0900 +++ b/include/llvm/Transforms/Scalar.h Thu Dec 12 23:38:21 2013 +0900 @@ -75,7 +75,11 @@ // // SROA - Replace aggregates or pieces of aggregates with scalar SSA values. // +#ifndef noCbC +FunctionPass *createSROAPass(bool RequiresDomTree = true,bool isOnlyForCbC = false); +#else FunctionPass *createSROAPass(bool RequiresDomTree = true); +#endif //===----------------------------------------------------------------------===// // @@ -250,7 +254,11 @@ // TailCallElimination - This pass eliminates call instructions to the current // function which occur immediately before return instructions. // +#ifndef noCbC +FunctionPass *createTailCallEliminationPass(bool isOnlyForCbC); +#else FunctionPass *createTailCallEliminationPass(); +#endif //===----------------------------------------------------------------------===// //
--- a/lib/Bitcode/Writer/BitcodeWriter.cpp Thu Dec 12 15:22:36 2013 +0900 +++ b/lib/Bitcode/Writer/BitcodeWriter.cpp Thu Dec 12 23:38:21 2013 +0900 @@ -383,6 +383,9 @@ switch (T->getTypeID()) { case Type::VoidTyID: Code = bitc::TYPE_CODE_VOID; break; +#ifndef noCbC + case Type::__CodeTyID: Code = bitc::TYPE_CODE_VOID; break; +#endif case Type::HalfTyID: Code = bitc::TYPE_CODE_HALF; break; case Type::FloatTyID: Code = bitc::TYPE_CODE_FLOAT; break; case Type::DoubleTyID: Code = bitc::TYPE_CODE_DOUBLE; break;
--- a/lib/CodeGen/Passes.cpp Thu Dec 12 15:22:36 2013 +0900 +++ b/lib/CodeGen/Passes.cpp Thu Dec 12 23:38:21 2013 +0900 @@ -415,7 +415,11 @@ /// Add pass to prepare the LLVM IR for code generation. This should be done /// before exception handling preparation passes. void TargetPassConfig::addCodeGenPrepare() { +#ifndef noCbC + if (((getOptLevel() != CodeGenOpt::None) || hasCodeSegment()) && !DisableCGP) +#else if (getOptLevel() != CodeGenOpt::None && !DisableCGP) +#endif addPass(createCodeGenPreparePass(TM)); }
--- a/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp Thu Dec 12 15:22:36 2013 +0900 +++ b/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp Thu Dec 12 23:38:21 2013 +0900 @@ -5440,6 +5440,11 @@ DAG.setRoot(DAG.getEHLabel(getCurSDLoc(), getControlRoot(), BeginLabel)); } +#ifndef noCbC + if (RetTy->is__CodeTy()) // force to set tail call flag if the called function is code segment. + isTailCall = true; +#endif + // Check if target-independent constraints permit a tail call here. // Target-dependent constraints are checked within TLI->LowerCallTo. if (isTailCall && !isInTailCallPosition(CS, *TLI)) @@ -5453,6 +5458,11 @@ "Non-null chain expected with non-tail call!"); assert((Result.second.getNode() || !Result.first.getNode()) && "Null value expected with tail call!"); +#ifndef noCbC + // if code segment's tail call flag was changed false , we report it on error. + if (CLI.RetTy->is__CodeTy() && CS.getCaller()->getReturnType()->is__CodeTy() && !isTailCall) + DAG.getContext()->emitError(CS.getInstruction(),CS.getCalledFunction()->getName() + " : Tail call elimination was failed!"); +#endif if (Result.first.getNode()) { setValue(CS.getInstruction(), Result.first); } else if (!CanLowerReturn && Result.second.getNode()) {
--- a/lib/ExecutionEngine/Interpreter/Execution.cpp Thu Dec 12 15:22:36 2013 +0900 +++ b/lib/ExecutionEngine/Interpreter/Execution.cpp Thu Dec 12 23:38:21 2013 +0900 @@ -2130,6 +2130,9 @@ switch (I.getType()->getTypeID()) { default: llvm_unreachable("Invalid GenericValue Type"); case Type::VoidTyID: dbgs() << "void"; break; +#ifndef noCbC + case Type::__CodeTyID: dbgs() << "void"; break; +#endif case Type::FloatTyID: dbgs() << "float " << Val.FloatVal; break; case Type::DoubleTyID: dbgs() << "double " << Val.DoubleVal; break; case Type::PointerTyID: dbgs() << "void* " << intptr_t(Val.PointerVal);
--- a/lib/ExecutionEngine/Interpreter/ExternalFunctions.cpp Thu Dec 12 15:22:36 2013 +0900 +++ b/lib/ExecutionEngine/Interpreter/ExternalFunctions.cpp Thu Dec 12 23:38:21 2013 +0900 @@ -63,6 +63,9 @@ static char getTypeID(Type *Ty) { switch (Ty->getTypeID()) { case Type::VoidTyID: return 'V'; +#ifndef noCbC + case Type::__CodeTyID: return 'V'; +#endif case Type::IntegerTyID: switch (cast<IntegerType>(Ty)->getBitWidth()) { case 1: return 'o'; @@ -113,6 +116,9 @@ static ffi_type *ffiTypeFor(Type *Ty) { switch (Ty->getTypeID()) { case Type::VoidTyID: return &ffi_type_void; +#ifndef noCbC + case Type::__CodeTyID: return &ffi_type_void; +#endif case Type::IntegerTyID: switch (cast<IntegerType>(Ty)->getBitWidth()) { case 8: return &ffi_type_sint8; @@ -220,7 +226,11 @@ if (ffi_prep_cif(&cif, FFI_DEFAULT_ABI, NumArgs, rtype, &args[0]) == FFI_OK) { SmallVector<uint8_t, 128> ret; +#ifndef noCbC + if (RetTy->getTypeID() != Type::VoidTyID && RetTy->getTypeID() != Type::__CodeTyID) +#else if (RetTy->getTypeID() != Type::VoidTyID) +#endif ret.resize(TD->getTypeStoreSize(RetTy)); ffi_call(&cif, Fn, ret.data(), values.data()); switch (RetTy->getTypeID()) {
--- a/lib/ExecutionEngine/JIT/JIT.cpp Thu Dec 12 15:22:36 2013 +0900 +++ b/lib/ExecutionEngine/JIT/JIT.cpp Thu Dec 12 23:38:21 2013 +0900 @@ -315,6 +315,9 @@ return rv; } case Type::VoidTyID: +#ifndef noCbC + case Type::__CodeTyID: +#endif rv.IntVal = APInt(32, ((int(*)())(intptr_t)FPtr)()); return rv; case Type::FloatTyID:
--- a/lib/ExecutionEngine/MCJIT/MCJIT.cpp Thu Dec 12 15:22:36 2013 +0900 +++ b/lib/ExecutionEngine/MCJIT/MCJIT.cpp Thu Dec 12 23:38:21 2013 +0900 @@ -456,6 +456,9 @@ return rv; } case Type::VoidTyID: +#ifndef noCbC + case Type::__CodeTyID: +#endif rv.IntVal = APInt(32, ((int(*)())(intptr_t)FPtr)()); return rv; case Type::FloatTyID:
--- a/lib/IR/AsmWriter.cpp Thu Dec 12 15:22:36 2013 +0900 +++ b/lib/IR/AsmWriter.cpp Thu Dec 12 23:38:21 2013 +0900 @@ -193,6 +193,9 @@ void TypePrinting::print(Type *Ty, raw_ostream &OS) { switch (Ty->getTypeID()) { case Type::VoidTyID: OS << "void"; return; +#ifndef noCbC + case Type::__CodeTyID: OS << "void"; break; +#endif case Type::HalfTyID: OS << "half"; return; case Type::FloatTyID: OS << "float"; return; case Type::DoubleTyID: OS << "double"; return;
--- a/lib/IR/Core.cpp Thu Dec 12 15:22:36 2013 +0900 +++ b/lib/IR/Core.cpp Thu Dec 12 23:38:21 2013 +0900 @@ -176,6 +176,9 @@ LLVMTypeKind LLVMGetTypeKind(LLVMTypeRef Ty) { switch (unwrap(Ty)->getTypeID()) { case Type::VoidTyID: +#ifndef noCbC + case Type::__CodeTyID: +#endif return LLVMVoidTypeKind; case Type::HalfTyID: return LLVMHalfTypeKind;
--- a/lib/IR/LLVMContextImpl.cpp Thu Dec 12 15:22:36 2013 +0900 +++ b/lib/IR/LLVMContextImpl.cpp Thu Dec 12 23:38:21 2013 +0900 @@ -30,6 +30,9 @@ FP128Ty(C, Type::FP128TyID), PPC_FP128Ty(C, Type::PPC_FP128TyID), X86_MMXTy(C, Type::X86_MMXTyID), +#ifndef noCbC + __CodeTy(C, Type::__CodeTyID), +#endif Int1Ty(C, 1), Int8Ty(C, 8), Int16Ty(C, 16),
--- a/lib/IR/LLVMContextImpl.h Thu Dec 12 15:22:36 2013 +0900 +++ b/lib/IR/LLVMContextImpl.h Thu Dec 12 23:38:21 2013 +0900 @@ -294,6 +294,9 @@ // Basic type instances. Type VoidTy, LabelTy, HalfTy, FloatTy, DoubleTy, MetadataTy; Type X86_FP80Ty, FP128Ty, PPC_FP128Ty, X86_MMXTy; +#ifndef noCbC + Type __CodeTy; +#endif IntegerType Int1Ty, Int8Ty, Int16Ty, Int32Ty, Int64Ty;
--- a/lib/IR/Type.cpp Thu Dec 12 15:22:36 2013 +0900 +++ b/lib/IR/Type.cpp Thu Dec 12 23:38:21 2013 +0900 @@ -35,6 +35,9 @@ case LabelTyID : return getLabelTy(C); case MetadataTyID : return getMetadataTy(C); case X86_MMXTyID : return getX86_MMXTy(C); +#ifndef noCbC + case __CodeTyID : return get__CodeTy(C); +#endif default: return 0; } @@ -228,6 +231,9 @@ Type *Type::getFP128Ty(LLVMContext &C) { return &C.pImpl->FP128Ty; } Type *Type::getPPC_FP128Ty(LLVMContext &C) { return &C.pImpl->PPC_FP128Ty; } Type *Type::getX86_MMXTy(LLVMContext &C) { return &C.pImpl->X86_MMXTy; } +#ifndef noCbC +Type *Type::get__CodeTy(LLVMContext &C) { return &C.pImpl->__CodeTy; } +#endif IntegerType *Type::getInt1Ty(LLVMContext &C) { return &C.pImpl->Int1Ty; } IntegerType *Type::getInt8Ty(LLVMContext &C) { return &C.pImpl->Int8Ty; }
--- a/lib/IR/ValueTypes.cpp Thu Dec 12 15:22:36 2013 +0900 +++ b/lib/IR/ValueTypes.cpp Thu Dec 12 23:38:21 2013 +0900 @@ -250,6 +250,9 @@ if (HandleUnknown) return MVT(MVT::Other); llvm_unreachable("Unknown type!"); case Type::VoidTyID: +#ifndef noCbC + case Type::__CodeTyID: +#endif return MVT::isVoid; case Type::IntegerTyID: return getIntegerVT(cast<IntegerType>(Ty)->getBitWidth());
--- a/lib/Target/NVPTX/NVPTXAsmPrinter.cpp Thu Dec 12 15:22:36 2013 +0900 +++ b/lib/Target/NVPTX/NVPTXAsmPrinter.cpp Thu Dec 12 23:38:21 2013 +0900 @@ -424,7 +424,11 @@ bool isABI = (nvptxSubtarget.getSmVersion() >= 20); +#ifndef noCbC + if (Ty->getTypeID() == Type::VoidTyID || Ty->getTypeID() == Type::__CodeTyID) +#else if (Ty->getTypeID() == Type::VoidTyID) +#endif return; O << " (";
--- a/lib/Target/NVPTX/NVPTXISelLowering.cpp Thu Dec 12 15:22:36 2013 +0900 +++ b/lib/Target/NVPTX/NVPTXISelLowering.cpp Thu Dec 12 23:38:21 2013 +0900 @@ -357,7 +357,11 @@ std::stringstream O; O << "prototype_" << uniqueCallSite << " : .callprototype "; +#ifndef noCbC + if (retTy->getTypeID() == Type::VoidTyID || retTy->getTypeID() == Type::__CodeTyID) { +#else if (retTy->getTypeID() == Type::VoidTyID) { +#endif O << "()"; } else { O << "(";
--- a/lib/Target/XCore/XCoreISelLowering.cpp Thu Dec 12 15:22:36 2013 +0900 +++ b/lib/Target/XCore/XCoreISelLowering.cpp Thu Dec 12 23:38:21 2013 +0900 @@ -1639,7 +1639,11 @@ bool XCoreTargetLowering::isLegalAddressingMode(const AddrMode &AM, Type *Ty) const { +#ifndef noCbC + if (Ty->getTypeID() == Type::VoidTyID || Ty->getTypeID() == Type::__CodeTyID) +#else if (Ty->getTypeID() == Type::VoidTyID) +#endif return AM.Scale == 0 && isImmUs(AM.BaseOffs) && isImmUs4(AM.BaseOffs); const DataLayout *TD = TM.getDataLayout();
--- a/lib/Transforms/IPO/MergeFunctions.cpp Thu Dec 12 15:22:36 2013 +0900 +++ b/lib/Transforms/IPO/MergeFunctions.cpp Thu Dec 12 23:38:21 2013 +0900 @@ -242,6 +242,9 @@ case Type::PPC_FP128TyID: case Type::LabelTyID: case Type::MetadataTyID: +#ifndef noCbC + case Type::__CodeTyID: +#endif return true; case Type::PointerTyID: {
--- a/lib/Transforms/IPO/PassManagerBuilder.cpp Thu Dec 12 15:22:36 2013 +0900 +++ b/lib/Transforms/IPO/PassManagerBuilder.cpp Thu Dec 12 23:38:21 2013 +0900 @@ -110,15 +110,29 @@ // Add LibraryInfo if we have some. if (LibraryInfo) FPM.add(new TargetLibraryInfo(*LibraryInfo)); +#ifndef noCbC + if (UseNewSROA) + FPM.add(createSROAPass(true,true)); + else + FPM.add(createScalarReplAggregatesPass()); +#endif + if (OptLevel == 0) return; addInitialAliasAnalysisPasses(FPM); FPM.add(createCFGSimplificationPass()); +#ifndef noCbC + if (UseNewSROA) + FPM.add(createSROAPass(true,false)); + else + FPM.add(createScalarReplAggregatesPass()); +#else if (UseNewSROA) FPM.add(createSROAPass()); else FPM.add(createScalarReplAggregatesPass()); +#endif FPM.add(createEarlyCSEPass()); FPM.add(createLowerExpectIntrinsicPass()); } @@ -138,6 +152,10 @@ if (!GlobalExtensions->empty() || !Extensions.empty()) MPM.add(createBarrierNoopPass()); +#ifndef noCbC + MPM.add(createTailCallEliminationPass(true)); // Eliminate tail calls +#endif + addExtensionsToPM(EP_EnabledOnOptLevel0, MPM); return; } @@ -173,17 +191,28 @@ // Start of function pass. // Break up aggregate allocas, using SSAUpdater. +#ifndef noCbC + if (UseNewSROA) + MPM.add(createSROAPass(/*RequiresDomTree*/ false,false)); + else + MPM.add(createScalarReplAggregatesPass(-1, false)); +#else if (UseNewSROA) MPM.add(createSROAPass(/*RequiresDomTree*/ false)); else MPM.add(createScalarReplAggregatesPass(-1, false)); +#endif MPM.add(createEarlyCSEPass()); // Catch trivial redundancies MPM.add(createJumpThreadingPass()); // Thread jumps. MPM.add(createCorrelatedValuePropagationPass()); // Propagate conditionals MPM.add(createCFGSimplificationPass()); // Merge & remove BBs MPM.add(createInstructionCombiningPass()); // Combine silly seq's +#ifndef noCbC + MPM.add(createTailCallEliminationPass(true)); // Eliminate tail calls +#else MPM.add(createTailCallEliminationPass()); // Eliminate tail calls +#endif MPM.add(createCFGSimplificationPass()); // Merge & remove BBs MPM.add(createReassociatePass()); // Reassociate expressions MPM.add(createLoopRotatePass()); // Rotate Loop
--- a/lib/Transforms/Scalar/SROA.cpp Thu Dec 12 15:22:36 2013 +0900 +++ b/lib/Transforms/Scalar/SROA.cpp Thu Dec 12 23:38:21 2013 +0900 @@ -894,11 +894,20 @@ SetVector<SelectInst *, SmallVector<SelectInst *, 2> > SpeculatableSelects; public: +#ifndef noCbC + SROA(bool RequiresDomTree = true,bool f = false) + : FunctionPass(ID), RequiresDomTree(RequiresDomTree), + C(0), DL(0), DT(0) { + initializeSROAPass(*PassRegistry::getPassRegistry()); + onlyForCbC = f; + } +#else SROA(bool RequiresDomTree = true) : FunctionPass(ID), RequiresDomTree(RequiresDomTree), C(0), DL(0), DT(0) { initializeSROAPass(*PassRegistry::getPassRegistry()); } +#endif bool runOnFunction(Function &F); void getAnalysisUsage(AnalysisUsage &AU) const; @@ -917,14 +926,25 @@ bool runOnAlloca(AllocaInst &AI); void deleteDeadInstructions(SmallPtrSet<AllocaInst *, 4> &DeletedAllocas); bool promoteAllocas(Function &F); +#ifndef noCbC + bool onlyForCbC; +public: + bool isOnlyForCbC(); +#endif }; } char SROA::ID = 0; +#ifndef noCbC +FunctionPass *llvm::createSROAPass(bool RequiresDomTree,bool isOnlyForCbC) { + return new SROA(RequiresDomTree,isOnlyForCbC); +} +#else FunctionPass *llvm::createSROAPass(bool RequiresDomTree) { return new SROA(RequiresDomTree); } +#endif INITIALIZE_PASS_BEGIN(SROA, "sroa", "Scalar Replacement Of Aggregates", false, false) @@ -3545,6 +3565,11 @@ } DT = getAnalysisIfAvailable<DominatorTree>(); +#ifndef noCbC + if (isOnlyForCbC() && !F.getReturnType()->is__CodeTy()) + return false; +#endif + BasicBlock &EntryBB = F.getEntryBlock(); for (BasicBlock::iterator I = EntryBB.begin(), E = llvm::prior(EntryBB.end()); I != E; ++I) @@ -3588,3 +3613,9 @@ AU.addRequired<DominatorTree>(); AU.setPreservesCFG(); } + +#ifndef noCbC +bool SROA::isOnlyForCbC(){ + return onlyForCbC; +} +#endif
--- a/lib/Transforms/Scalar/Scalar.cpp Thu Dec 12 15:22:36 2013 +0900 +++ b/lib/Transforms/Scalar/Scalar.cpp Thu Dec 12 23:38:21 2013 +0900 @@ -168,7 +168,11 @@ } void LLVMAddTailCallEliminationPass(LLVMPassManagerRef PM) { +#ifndef noCbC + unwrap(PM)->add(createTailCallEliminationPass(false)); +#else unwrap(PM)->add(createTailCallEliminationPass()); +#endif } void LLVMAddConstantPropagationPass(LLVMPassManagerRef PM) {
--- a/lib/Transforms/Scalar/TailRecursionElimination.cpp Thu Dec 12 15:22:36 2013 +0900 +++ b/lib/Transforms/Scalar/TailRecursionElimination.cpp Thu Dec 12 23:38:21 2013 +0900 @@ -88,6 +88,12 @@ TailCallElim() : FunctionPass(ID) { initializeTailCallElimPass(*PassRegistry::getPassRegistry()); } +#ifndef noCbC + TailCallElim(bool f) : FunctionPass(ID) { + initializeTailCallElimPass(*PassRegistry::getPassRegistry()); + onlyForCbC = f; + } +#endif virtual void getAnalysisUsage(AnalysisUsage &AU) const; @@ -112,6 +118,11 @@ bool CannotTailCallElimCallsMarkedTail); bool CanMoveAboveCall(Instruction *I, CallInst *CI); Value *CanTransformAccumulatorRecursion(Instruction *I, CallInst *CI); +#ifndef noCbC + bool onlyForCbC; + public: + bool isOnlyForCbC(); +#endif }; } @@ -123,9 +134,16 @@ "Tail Call Elimination", false, false) // Public interface to the TailCallElimination pass +#ifndef noCbC +// Public interface to the TailCallElimination pass +FunctionPass *llvm::createTailCallEliminationPass(bool isOnlyForCbC) { + return new TailCallElim(isOnlyForCbC); +} +#else FunctionPass *llvm::createTailCallEliminationPass() { return new TailCallElim(); } +#endif void TailCallElim::getAnalysisUsage(AnalysisUsage &AU) const { AU.addRequired<TargetTransformInfo>(); @@ -249,6 +267,13 @@ for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; ++I) { if (CallInst *CI = dyn_cast<CallInst>(I)) { if (!ACT.UsesAlloca.count(CI)) { +#ifndef noCbC + if (isOnlyForCbC()){ + Function* CalledFunction = CI->getCalledFunction(); + if (CalledFunction == NULL || !CalledFunction->getReturnType()->is__CodeTy()) + continue; + } +#endif CI->setTailCall(); MadeChange = true; } @@ -670,3 +695,9 @@ ArgumentPHIs, CannotTailCallElimCallsMarkedTail); } + +#ifndef noCbC + bool TailCallElim::isOnlyForCbC(){ + return onlyForCbC; +} +#endif
--- a/tools/clang/include/clang/AST/ASTContext.h Thu Dec 12 15:22:36 2013 +0900 +++ b/tools/clang/include/clang/AST/ASTContext.h Thu Dec 12 23:38:21 2013 +0900 @@ -765,6 +765,9 @@ // Builtin Types. CanQualType VoidTy; +#ifndef noCbC + CanQualType __CodeTy; +#endif CanQualType BoolTy; CanQualType CharTy; CanQualType WCharTy; // [C++ 3.9.1p5].
--- a/tools/clang/include/clang/AST/BuiltinTypes.def Thu Dec 12 15:22:36 2013 +0900 +++ b/tools/clang/include/clang/AST/BuiltinTypes.def Thu Dec 12 23:38:21 2013 +0900 @@ -58,6 +58,9 @@ // void BUILTIN_TYPE(Void, VoidTy) +#ifndef noCbC +BUILTIN_TYPE(__Code, __CodeTy) +#endif //===- Unsigned Types -----------------------------------------------------===// // 'bool' in C++, '_Bool' in C99
--- a/tools/clang/include/clang/AST/CanonicalType.h Thu Dec 12 15:22:36 2013 +0900 +++ b/tools/clang/include/clang/AST/CanonicalType.h Thu Dec 12 23:38:21 2013 +0900 @@ -267,6 +267,9 @@ LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isRealType) LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isArithmeticType) LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isVoidType) +#ifndef noCbC + LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, is__CodeType) +#endif LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isDerivedType) LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isScalarType) LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isAggregateType)
--- a/tools/clang/include/clang/AST/Type.h Thu Dec 12 15:22:36 2013 +0900 +++ b/tools/clang/include/clang/AST/Type.h Thu Dec 12 23:38:21 2013 +0900 @@ -1519,6 +1519,10 @@ bool isFundamentalType() const; bool isCompoundType() const; +#ifndef noCbC + bool is__CodeType() const; // for CbC +#endif + // Type Predicates: Check to see if this type is structurally the specified // type, ignoring typedefs and qualifiers. bool isFunctionType() const; @@ -5060,10 +5064,22 @@ inline bool Type::isVoidType() const { if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType)) +#ifndef noCbC + return (BT->getKind() == BuiltinType::Void || BT->getKind() == BuiltinType::__Code); +#else return BT->getKind() == BuiltinType::Void; +#endif return false; } +#ifndef noCbC +inline bool Type::is__CodeType() const { + if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType)) + return BT->getKind() == BuiltinType::__Code; + return false; +} +#endif + inline bool Type::isHalfType() const { if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType)) return BT->getKind() == BuiltinType::Half; @@ -5095,8 +5111,14 @@ inline bool Type::isScalarType() const { if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType)) +#ifndef noCbC + return BT->getKind() > BuiltinType::Void && + BT->getKind() <= BuiltinType::NullPtr && + BT->getKind() != BuiltinType::__Code; +#else return BT->getKind() > BuiltinType::Void && BT->getKind() <= BuiltinType::NullPtr; +#endif if (const EnumType *ET = dyn_cast<EnumType>(CanonicalType)) // Enums are scalar types, but only if they are defined. Incomplete enums // are not treated as scalar types.
--- a/tools/clang/include/clang/Basic/LangOptions.def Thu Dec 12 15:22:36 2013 +0900 +++ b/tools/clang/include/clang/Basic/LangOptions.def Thu Dec 12 23:38:21 2013 +0900 @@ -180,6 +180,10 @@ BENIGN_LANGOPT(RetainCommentsFromSystemHeaders, 1, 0, "retain documentation comments from system headers in the AST") +#ifndef noCbC +LANGOPT(HasCodeSegment , 1, 0, "CbC") +#endif + #undef LANGOPT #undef VALUE_LANGOPT #undef BENIGN_LANGOPT
--- a/tools/clang/include/clang/Basic/Specifiers.h Thu Dec 12 15:22:36 2013 +0900 +++ b/tools/clang/include/clang/Basic/Specifiers.h Thu Dec 12 23:38:21 2013 +0900 @@ -71,6 +71,11 @@ TST_image3d_t, // OpenCL image3d_t TST_sampler_t, // OpenCL sampler_t TST_event_t, // OpenCL event_t + +#ifndef noCbC + TST___code, +#endif + TST_error // erroneous type };
--- a/tools/clang/include/clang/Basic/TokenKinds.def Thu Dec 12 15:22:36 2013 +0900 +++ b/tools/clang/include/clang/Basic/TokenKinds.def Thu Dec 12 23:38:21 2013 +0900 @@ -267,6 +267,9 @@ KEYWORD(__objc_yes , KEYALL) KEYWORD(__objc_no , KEYALL) +#ifndef noCbC +KEYWORD(__code , KEYALL) +#endif // C++ 2.11p1: Keywords. KEYWORD(asm , KEYCXX|KEYGNU)
--- a/tools/clang/include/clang/Parse/Parser.h Thu Dec 12 15:22:36 2013 +0900 +++ b/tools/clang/include/clang/Parse/Parser.h Thu Dec 12 23:38:21 2013 +0900 @@ -1531,6 +1531,9 @@ StmtResult ParseDoStatement(); StmtResult ParseForStatement(SourceLocation *TrailingElseLoc); StmtResult ParseGotoStatement(); +#ifndef noCbC + StmtResult ParseCbCGotoStatement(ParsedAttributesWithRange &Attrs,StmtVector &Stmts); +#endif StmtResult ParseContinueStatement(); StmtResult ParseBreakStatement(); StmtResult ParseReturnStatement(); @@ -1694,6 +1697,13 @@ void ParseStructDeclaration(ParsingDeclSpec &DS, FieldCallback &Callback); +#ifndef noCbC + bool Create__CbC_envStruct(SourceLocation Loc, AccessSpecifier AS); + IdentifierInfo* CreateIdentifierInfo(const char* Name, int NameLen); + Decl* Create__CbC_envBody(Decl* TagDecl, DeclSpec::TST T, SourceLocation Loc, bool* isInvalid, + const char* PrevSpec, unsigned* DiagID, const char* Name, int NameLen); +#endif + bool isDeclarationSpecifier(bool DisambiguatingWithExpression = false); bool isTypeSpecifierQualifier(); bool isTypeQualifier() const;
--- a/tools/clang/include/clang/Sema/DeclSpec.h Thu Dec 12 15:22:36 2013 +0900 +++ b/tools/clang/include/clang/Sema/DeclSpec.h Thu Dec 12 23:38:21 2013 +0900 @@ -295,6 +295,9 @@ static const TST TST_event_t = clang::TST_event_t; static const TST TST_error = clang::TST_error; +#ifndef noCbC + static const TST TST___code = clang::TST___code; +#endif // type-qualifiers enum TQ { // NOTE: These flags must be kept in sync with Qualifiers::TQ. TQ_unspecified = 0,
--- a/tools/clang/include/clang/Serialization/ASTBitCodes.h Thu Dec 12 15:22:36 2013 +0900 +++ b/tools/clang/include/clang/Serialization/ASTBitCodes.h Thu Dec 12 23:38:21 2013 +0900 @@ -743,6 +743,10 @@ PREDEF_TYPE_EVENT_ID = 44, /// \brief OpenCL sampler type. PREDEF_TYPE_SAMPLER_ID = 45 +#ifndef noCbC + /// \brief The void type. + ,PREDEF_TYPE___CODE_ID = 46 +#endif }; /// \brief The number of predefined type IDs that are reserved for
--- a/tools/clang/lib/AST/ASTContext.cpp Thu Dec 12 15:22:36 2013 +0900 +++ b/tools/clang/lib/AST/ASTContext.cpp Thu Dec 12 23:38:21 2013 +0900 @@ -919,6 +919,11 @@ // C99 6.2.5p19. InitBuiltinType(VoidTy, BuiltinType::Void); +#ifndef noCbC + // CbC + InitBuiltinType(__CodeTy, BuiltinType::__Code); +#endif + // C99 6.2.5p2. InitBuiltinType(BoolTy, BuiltinType::Bool); // C99 6.2.5p3. @@ -1492,6 +1497,9 @@ default: llvm_unreachable("Unknown builtin type!"); case BuiltinType::Void: // GCC extension: alignof(void) = 8 bits. +#ifndef noCbC + case BuiltinType::__Code: +#endif Width = 0; Align = 8; break;
--- a/tools/clang/lib/AST/ItaniumMangle.cpp Thu Dec 12 15:22:36 2013 +0900 +++ b/tools/clang/lib/AST/ItaniumMangle.cpp Thu Dec 12 23:38:21 2013 +0900 @@ -1935,6 +1935,9 @@ // ::= u <source-name> # vendor extended type switch (T->getKind()) { case BuiltinType::Void: Out << 'v'; break; +#ifndef noCbC + case BuiltinType::__Code: Out << 'v'; break; +#endif case BuiltinType::Bool: Out << 'b'; break; case BuiltinType::Char_U: case BuiltinType::Char_S: Out << 'c'; break; case BuiltinType::UChar: Out << 'h'; break;
--- a/tools/clang/lib/AST/MicrosoftMangle.cpp Thu Dec 12 15:22:36 2013 +0900 +++ b/tools/clang/lib/AST/MicrosoftMangle.cpp Thu Dec 12 23:38:21 2013 +0900 @@ -1214,6 +1214,9 @@ // ::= _Z # __float80 (Digital Mars) switch (T->getKind()) { case BuiltinType::Void: Out << 'X'; break; +#ifndef noCbC + case BuiltinType::__Code: Out << 'X'; break; +#endif case BuiltinType::SChar: Out << 'C'; break; case BuiltinType::Char_U: case BuiltinType::Char_S: Out << 'D'; break; case BuiltinType::UChar: Out << 'E'; break;
--- a/tools/clang/lib/AST/NSAPI.cpp Thu Dec 12 15:22:36 2013 +0900 +++ b/tools/clang/lib/AST/NSAPI.cpp Thu Dec 12 23:38:21 2013 +0900 @@ -333,6 +333,9 @@ return NSAPI::NSNumberWithBool; case BuiltinType::Void: +#ifndef noCbC + case BuiltinType::__Code: +#endif case BuiltinType::WChar_U: case BuiltinType::WChar_S: case BuiltinType::Char16:
--- a/tools/clang/lib/AST/Type.cpp Thu Dec 12 15:22:36 2013 +0900 +++ b/tools/clang/lib/AST/Type.cpp Thu Dec 12 23:38:21 2013 +0900 @@ -1504,6 +1504,9 @@ StringRef BuiltinType::getName(const PrintingPolicy &Policy) const { switch (getKind()) { case Void: return "void"; +#ifndef noCbC + case __Code: return "__code"; +#endif case Bool: return Policy.Bool ? "bool" : "_Bool"; case Char_S: return "char"; case Char_U: return "char";
--- a/tools/clang/lib/AST/TypeLoc.cpp Thu Dec 12 15:22:36 2013 +0900 +++ b/tools/clang/lib/AST/TypeLoc.cpp Thu Dec 12 23:38:21 2013 +0900 @@ -250,6 +250,10 @@ switch (getTypePtr()->getKind()) { case BuiltinType::Void: return TST_void; +#ifndef noCbC + case BuiltinType::__Code: + return TST___code; +#endif case BuiltinType::Bool: return TST_bool; case BuiltinType::Char_U:
--- a/tools/clang/lib/Analysis/FormatString.cpp Thu Dec 12 15:22:36 2013 +0900 +++ b/tools/clang/lib/Analysis/FormatString.cpp Thu Dec 12 23:38:21 2013 +0900 @@ -341,6 +341,9 @@ case BuiltinType::UChar: case BuiltinType::Char_S: case BuiltinType::SChar: +#ifndef noCbC + case BuiltinType::__Code: +#endif return true; default: break;
--- a/tools/clang/lib/CodeGen/BackendUtil.cpp Thu Dec 12 15:22:36 2013 +0900 +++ b/tools/clang/lib/CodeGen/BackendUtil.cpp Thu Dec 12 23:38:21 2013 +0900 @@ -483,6 +483,10 @@ Options.TrapFuncName = CodeGenOpts.TrapFuncName; Options.PositionIndependentExecutable = LangOpts.PIELevel != 0; Options.EnableSegmentedStacks = CodeGenOpts.EnableSegmentedStacks; +#ifndef noCbC + Options.HasCodeSegment = LangOpts.HasCodeSegment; + Options.GuaranteedTailCallOpt = LangOpts.HasCodeSegment; +#endif TargetMachine *TM = TheTarget->createTargetMachine(Triple, TargetOpts.CPU, FeaturesStr, Options,
--- a/tools/clang/lib/CodeGen/CGCall.cpp Thu Dec 12 15:22:36 2013 +0900 +++ b/tools/clang/lib/CodeGen/CGCall.cpp Thu Dec 12 23:38:21 2013 +0900 @@ -447,6 +447,16 @@ if (FI) return *FI; +#ifndef noCbC + // if the function is a code segment , set fastcall calling convention. + if(resultType.getTypePtr()->is__CodeType()){ + if(!required.allowsOptionalArgs()) // If the code segment is a variadic function , LLVM can't do TCE. + CC = llvm::CallingConv::Fast; + else + resultType = Context.VoidTy; + } +#endif + // Construct the function info. We co-allocate the ArgInfos. FI = CGFunctionInfo::create(CC, info, resultType, argTypes, required); FunctionInfos.InsertNode(FI, insertPos); @@ -914,7 +924,14 @@ } case ABIArgInfo::Ignore: +#ifndef noCbC + if (FI.getReturnType().getTypePtr()->is__CodeType()) + resultType = llvm::Type::get__CodeTy(getLLVMContext()); + else + resultType = llvm::Type::getVoidTy(getLLVMContext()); +#else resultType = llvm::Type::getVoidTy(getLLVMContext()); +#endif break; }
--- a/tools/clang/lib/CodeGen/CGDebugInfo.cpp Thu Dec 12 15:22:36 2013 +0900 +++ b/tools/clang/lib/CodeGen/CGDebugInfo.cpp Thu Dec 12 23:38:21 2013 +0900 @@ -400,6 +400,9 @@ case BuiltinType::NullPtr: return DBuilder.createNullPtrType(); case BuiltinType::Void: +#ifndef noCbC + case BuiltinType::__Code: +#endif return llvm::DIType(); case BuiltinType::ObjCClass: if (ClassTy)
--- a/tools/clang/lib/CodeGen/CGRTTI.cpp Thu Dec 12 15:22:36 2013 +0900 +++ b/tools/clang/lib/CodeGen/CGRTTI.cpp Thu Dec 12 23:38:21 2013 +0900 @@ -167,6 +167,9 @@ // half-precision floating point types. switch (Ty->getKind()) { case BuiltinType::Void: +#ifndef noCbC + case BuiltinType::__Code: +#endif case BuiltinType::NullPtr: case BuiltinType::Bool: case BuiltinType::WChar_S:
--- a/tools/clang/lib/CodeGen/CodeGenTypes.cpp Thu Dec 12 15:22:36 2013 +0900 +++ b/tools/clang/lib/CodeGen/CodeGenTypes.cpp Thu Dec 12 23:38:21 2013 +0900 @@ -320,6 +320,9 @@ case Type::Builtin: { switch (cast<BuiltinType>(Ty)->getKind()) { case BuiltinType::Void: +#ifndef noCbC + case BuiltinType::__Code: +#endif case BuiltinType::ObjCId: case BuiltinType::ObjCClass: case BuiltinType::ObjCSel:
--- a/tools/clang/lib/CodeGen/TargetInfo.cpp Thu Dec 12 15:22:36 2013 +0900 +++ b/tools/clang/lib/CodeGen/TargetInfo.cpp Thu Dec 12 23:38:21 2013 +0900 @@ -1456,7 +1456,11 @@ if (const BuiltinType *BT = Ty->getAs<BuiltinType>()) { BuiltinType::Kind k = BT->getKind(); +#ifndef noCbC + if (k == BuiltinType::Void || k == BuiltinType::__Code) { +#else if (k == BuiltinType::Void) { +#endif Current = NoClass; } else if (k == BuiltinType::Int128 || k == BuiltinType::UInt128) { Lo = Integer;
--- a/tools/clang/lib/Driver/Types.cpp Thu Dec 12 15:22:36 2013 +0900 +++ b/tools/clang/lib/Driver/Types.cpp Thu Dec 12 23:38:21 2013 +0900 @@ -174,6 +174,9 @@ .Case("F95", TY_Fortran) .Case("mii", TY_PP_ObjCXX) .Case("pcm", TY_ModuleFile) +#ifndef noCbC + .Case("cbc", TY_C) +#endif .Default(TY_INVALID); }
--- a/tools/clang/lib/Format/TokenAnnotator.cpp Thu Dec 12 15:22:36 2013 +0900 +++ b/tools/clang/lib/Format/TokenAnnotator.cpp Thu Dec 12 23:38:21 2013 +0900 @@ -829,6 +829,9 @@ case tok::kw_signed: case tok::kw_unsigned: case tok::kw_void: +#ifndef noCbC + case tok::kw___code: +#endif case tok::kw_char: case tok::kw_int: case tok::kw_half:
--- a/tools/clang/lib/Frontend/CompilerInvocation.cpp Thu Dec 12 15:22:36 2013 +0900 +++ b/tools/clang/lib/Frontend/CompilerInvocation.cpp Thu Dec 12 23:38:21 2013 +0900 @@ -856,6 +856,9 @@ .Case("objective-c++-header", IK_ObjCXX) .Cases("ast", "pcm", IK_AST) .Case("ir", IK_LLVM_IR) +#ifndef noCbC + .Case("cbc", IK_C) +#endif .Default(IK_None); if (DashX == IK_None) Diags.Report(diag::err_drv_invalid_value)
--- a/tools/clang/lib/Frontend/FrontendOptions.cpp Thu Dec 12 15:22:36 2013 +0900 +++ b/tools/clang/lib/Frontend/FrontendOptions.cpp Thu Dec 12 23:38:21 2013 +0900 @@ -27,5 +27,8 @@ .Case("cl", IK_OpenCL) .Case("cu", IK_CUDA) .Cases("ll", "bc", IK_LLVM_IR) +#ifndef noCbC + .Case("cbc", IK_C) +#endif .Default(IK_C); }
--- a/tools/clang/lib/Parse/ParseDecl.cpp Thu Dec 12 15:22:36 2013 +0900 +++ b/tools/clang/lib/Parse/ParseDecl.cpp Thu Dec 12 23:38:21 2013 +0900 @@ -3117,6 +3117,24 @@ isInvalid = DS.SetTypeSpecType(DeclSpec::TST_void, Loc, PrevSpec, DiagID); break; +#ifndef noCbC + case tok::kw___code: { + // create __CbC_env + bool isInvalid__CbC_env = false; + if (getCurScope()->getParent() == NULL) // If the current scope has parent scope, it is not the glabal scope. + isInvalid__CbC_env = Create__CbC_envStruct(Loc,AS); + + if (DS.getSourceRange().isInvalid()) { + DS.SetRangeStart(Tok.getLocation()); + DS.SetRangeEnd(Tok.getLocation()); + } + LangOptions* LOP; + LOP = const_cast<LangOptions*>(&getLangOpts()); + LOP->HasCodeSegment = 1; + isInvalid = (DS.SetTypeSpecType(DeclSpec::TST___code, Loc, PrevSpec, DiagID) || isInvalid__CbC_env); + break; + } +#endif case tok::kw_char: isInvalid = DS.SetTypeSpecType(DeclSpec::TST_char, Loc, PrevSpec, DiagID); @@ -4066,6 +4084,9 @@ case tok::kw__Complex: case tok::kw__Imaginary: case tok::kw_void: +#ifndef noCbC + case tok::kw___code: +#endif case tok::kw_char: case tok::kw_wchar_t: case tok::kw_char16_t: @@ -4148,6 +4169,9 @@ case tok::kw__Complex: case tok::kw__Imaginary: case tok::kw_void: +#ifndef noCbC + case tok::kw___code: +#endif case tok::kw_char: case tok::kw_wchar_t: case tok::kw_char16_t: @@ -4303,6 +4327,9 @@ case tok::kw__Complex: case tok::kw__Imaginary: case tok::kw_void: +#ifndef noCbC + case tok::kw___code: +#endif case tok::kw_char: case tok::kw_wchar_t: case tok::kw_char16_t: @@ -5861,6 +5888,9 @@ case tok::kw_double: case tok::kw_bool: case tok::kw___pixel: +#ifndef noCbC + case tok::kw___code: +#endif Tok.setKind(tok::kw___vector); return true; case tok::identifier: @@ -5893,6 +5923,9 @@ case tok::kw_double: case tok::kw_bool: case tok::kw___pixel: +#ifndef noCbC + case tok::kw___code: +#endif isInvalid = DS.SetTypeAltiVecVector(true, Loc, PrevSpec, DiagID); return true; case tok::identifier: @@ -5919,3 +5952,108 @@ } return false; } + +#ifndef noCbC + +/// Create__CbC_envStruct - This method create "struct __CbC_env" which is used to continuation with environment. +/// If the __CbC_env has been already defined, it doesn't create __CbC_env again and just return "false". +bool Parser::Create__CbC_envStruct(SourceLocation Loc, AccessSpecifier AS) { + ParsingDeclSpec SDS(*this); + if (SDS.getSourceRange().isInvalid()) { + SDS.SetRangeStart(Loc); + SDS.SetRangeEnd(Loc); + } + IdentifierInfo *Name = CreateIdentifierInfo("__CbC_env", /* length of the name */ 9);; + + // Check previous definition. If the __CbC_env has been already defined, we have not to create again. + LookupResult Previous(Actions, Name, Loc, Actions.LookupTagName, Actions.ForRedeclaration); + if(Actions.LookupName(Previous, getCurScope())) + return false; + + // start ParseClassSpecifier + DeclSpec::TST TagType = DeclSpec::TST_struct; + DeclResult TagOrTempResult = true; // invalid + bool Owned = false; + bool IsDependent = false; + ParsedAttributesWithRange attrs(AttrFactory); + MultiTemplateParamsArg TParams; + + TagOrTempResult = Actions.ActOnTag(getCurScope(), TagType, Sema::TUK_Definition, Loc, + SDS.getTypeSpecScope(), Name, Loc, attrs.getList(), AS, + SDS.getModulePrivateSpecLoc(), TParams, Owned, IsDependent, + SourceLocation(), false, clang::TypeResult()); + // start ParseStructUnionBody + Decl *TagDecl = TagOrTempResult.get(); + PrettyDeclStackTraceEntry CrashInfo(Actions, TagDecl, Loc, "parsing struct/union body"); + ParseScope StructScope(this, Scope::ClassScope|Scope::DeclScope); + Actions.ActOnTagStartDefinition(getCurScope(), TagDecl); + SmallVector<Decl *, 32> FieldDecls; + + bool isInvalid = false; + const char *PrevSpec = 0; + unsigned DiagID = 0; + + // create struct body (void* ret_p, int* env) + FieldDecls.push_back(Create__CbC_envBody(TagDecl, DeclSpec::TST_void, Loc, &isInvalid, PrevSpec, &DiagID, "ret_p", /* length of the name */ 5)); + FieldDecls.push_back(Create__CbC_envBody(TagDecl, DeclSpec::TST_int, Loc, &isInvalid, PrevSpec, &DiagID, "env", /* length of the name */ 3)); + + Actions.ActOnFields(getCurScope(),Loc, TagDecl, FieldDecls,Loc, Loc,attrs.getList()); + StructScope.Exit(); + Actions.ActOnTagFinishDefinition(getCurScope(), TagDecl,Loc); + bool Result; + Result = SDS.SetTypeSpecType(TagType, Loc,Loc.isValid() ? Loc : Loc,PrevSpec, DiagID, TagOrTempResult.get(), Owned); + if (Result){ + Diag(Loc, DiagID) << PrevSpec; + } + SDS.Finish(Diags,PP); + Decl *TheDecl = Actions.ParsedFreeStandingDeclSpec(getCurScope(), AS, SDS); + SDS.complete(TheDecl); + Actions.ConvertDeclToDeclGroup(TheDecl); + return isInvalid; +} + +Decl* Parser::Create__CbC_envBody(Decl* TagDecl, DeclSpec::TST T, SourceLocation Loc, bool* isInvalid, + const char* PrevSpec, unsigned* DiagID, const char* Name, int NameLen){ + ParsingDeclSpec PDS(*this); + if (PDS.getSourceRange().isInvalid()) { + PDS.SetRangeStart(Loc); + PDS.SetRangeEnd(Loc); + } + *isInvalid = (PDS.SetTypeSpecType(T, Loc, PrevSpec, *DiagID) || *isInvalid); + PDS.SetRangeEnd(Loc); + + // star(*) + PDS.Finish(Diags, PP); + SourceLocation CommaLoc; + ParsingFieldDeclarator DeclaratorInfo(*this, PDS); + DeclaratorInfo.D.setCommaLoc(CommaLoc); + DeclaratorInfo.D.SetRangeEnd(Loc); + DeclSpec DS(AttrFactory); + DS.Finish(Diags,PP); + DeclaratorInfo.D.SetIdentifier(CreateIdentifierInfo(Name, NameLen),Loc); + // end of check star(*) + + DeclaratorInfo.D.AddTypeInfo(DeclaratorChunk::getPointer(DS.getTypeQualifiers(), Loc,DS.getConstSpecLoc(), + DS.getVolatileSpecLoc(),DS.getRestrictSpecLoc()), + DS.getAttributes(),SourceLocation()); + Decl *Field = Actions.ActOnField(getCurScope(), TagDecl, + DeclaratorInfo.D.getDeclSpec().getSourceRange().getBegin(), + DeclaratorInfo.D, DeclaratorInfo.BitfieldSize); + DeclaratorInfo.complete(Field); + return Field; +} + +IdentifierInfo* Parser::CreateIdentifierInfo(const char* Name, int NameLen) { + Token TokenForII; + TokenForII.startToken(); + TokenForII.setLength(NameLen); + TokenForII.setKind(tok::raw_identifier); + TokenForII.setRawIdentifierData(Name); + IdentifierInfo *II; + II = PP.getIdentifierInfo(StringRef(TokenForII.getRawIdentifierData(),TokenForII.getLength())); + TokenForII.setIdentifierInfo(II); + TokenForII.setKind(II->getTokenID()); + return II; +} + +#endif
--- a/tools/clang/lib/Parse/ParseExpr.cpp Thu Dec 12 15:22:36 2013 +0900 +++ b/tools/clang/lib/Parse/ParseExpr.cpp Thu Dec 12 23:38:21 2013 +0900 @@ -1026,6 +1026,9 @@ case tok::kw_float: case tok::kw_double: case tok::kw_void: +#ifndef noCbC + case tok::kw___code: +#endif case tok::kw_typename: case tok::kw_typeof: case tok::kw___vector:
--- a/tools/clang/lib/Parse/ParseStmt.cpp Thu Dec 12 15:22:36 2013 +0900 +++ b/tools/clang/lib/Parse/ParseStmt.cpp Thu Dec 12 23:38:21 2013 +0900 @@ -258,6 +258,12 @@ return ParseForStatement(TrailingElseLoc); case tok::kw_goto: // C99 6.8.6.1: goto-statement +#ifndef noCbC + if (PP.LookAhead(1).is(tok::l_paren)) { // is CbC goto : 'goto' codeSegment() ';' + SemiError = "goto code segment"; + return ParseCbCGotoStatement(Attrs, Stmts); + } +#endif Res = ParseGotoStatement(); SemiError = "goto"; break; @@ -1684,6 +1690,60 @@ return Res; } +#ifndef noCbC +/// ParseCbCGotoStatement +/// jump-statement: +/// 'goto' codeSegment ';' +/// +StmtResult Parser::ParseCbCGotoStatement(ParsedAttributesWithRange &Attrs,StmtVector &Stmts) { + assert(Tok.is(tok::kw_goto) && "Not a goto stmt!"); + SourceLocation gotoLoc = ConsumeToken(); // eat the 'goto'. + StmtResult gotoRes; + + if (Tok.is(tok::identifier) && NextToken().is(tok::l_paren)) { // 'goto' codeSegment() ';' + + CorrectionCandidateCallback DefaultValidator; + DefaultValidator.WantTypeSpecifiers = true; + DefaultValidator.WantExpressionKeywords = true; + DefaultValidator.WantRemainingKeywords = true; + DefaultValidator.WantCXXNamedCasts = false; + + if (TryAnnotateName(/*IsAddressOfOperand*/false, &DefaultValidator) + == ANK_Error) { + // Handle errors here by skipping up to the next semicolon or '}', and + // eat the semicolon if that's what stopped us. + SkipUntil(tok::r_brace, StopAtSemi | StopBeforeMatch); + if (Tok.is(tok::semi)) + ConsumeToken(); + return StmtError(); + } + + gotoRes = ParseExprStatement(); + + // don't need return because this code segment caller isn't code segment. + if (!Actions.getCurFunctionDecl()->getResultType().getTypePtr()->is__CodeType()) + return gotoRes; + + } + else { + Diag(Tok, diag::err_expected_ident); + return StmtError(); + } + assert((Attrs.empty() || gotoRes.isInvalid() || gotoRes.isUsable()) && + "attributes on empty statement"); + + if (!(Attrs.empty() || gotoRes.isInvalid())) + gotoRes = Actions.ProcessStmtAttributes(gotoRes.get(), Attrs.getList(), Attrs.Range); + + if(gotoRes.isUsable()) + Stmts.push_back(gotoRes.release()); + /* add return; after goto code segment. */ + + ExprResult R; + return Actions.ActOnReturnStmt(gotoLoc, R.take()); +} +#endif + /// ParseContinueStatement /// jump-statement: /// 'continue' ';'
--- a/tools/clang/lib/Parse/ParseTentative.cpp Thu Dec 12 15:22:36 2013 +0900 +++ b/tools/clang/lib/Parse/ParseTentative.cpp Thu Dec 12 23:38:21 2013 +0900 @@ -990,6 +990,9 @@ case tok::kw_union: case tok::kw_unsigned: case tok::kw_void: +#ifndef noCbC + case tok::kw___code: +#endif case tok::kw_volatile: case tok::kw__Bool: case tok::kw__Complex: @@ -1433,6 +1436,9 @@ case tok::kw_float: case tok::kw_double: case tok::kw_void: +#ifndef noCbC + case tok::kw___code: +#endif case tok::annot_decltype: if (NextToken().is(tok::l_paren)) return TPResult::Ambiguous(); @@ -1525,6 +1531,9 @@ case tok::kw_double: case tok::kw_void: case tok::kw___unknown_anytype: +#ifndef noCbC + case tok::kw___code: +#endif return true; case tok::kw_auto:
--- a/tools/clang/lib/Sema/DeclSpec.cpp Thu Dec 12 15:22:36 2013 +0900 +++ b/tools/clang/lib/Sema/DeclSpec.cpp Thu Dec 12 23:38:21 2013 +0900 @@ -293,6 +293,9 @@ case TST_image3d_t: case TST_sampler_t: case TST_event_t: +#ifndef noCbC + case TST___code: +#endif return false; case TST_decltype_auto: @@ -466,6 +469,9 @@ case DeclSpec::TST_sampler_t: return "sampler_t"; case DeclSpec::TST_event_t: return "event_t"; case DeclSpec::TST_error: return "(error)"; +#ifndef noCbC + case DeclSpec::TST___code: return "__code"; +#endif } llvm_unreachable("Unknown typespec!"); }
--- a/tools/clang/lib/Sema/SemaCodeComplete.cpp Thu Dec 12 15:22:36 2013 +0900 +++ b/tools/clang/lib/Sema/SemaCodeComplete.cpp Thu Dec 12 23:38:21 2013 +0900 @@ -587,6 +587,9 @@ case Type::Builtin: switch (cast<BuiltinType>(T)->getKind()) { case BuiltinType::Void: +#ifndef noCbC + case BuiltinType::__Code: +#endif return STC_Void; case BuiltinType::NullPtr:
--- a/tools/clang/lib/Sema/SemaTemplateVariadic.cpp Thu Dec 12 15:22:36 2013 +0900 +++ b/tools/clang/lib/Sema/SemaTemplateVariadic.cpp Thu Dec 12 23:38:21 2013 +0900 @@ -739,6 +739,9 @@ case TST_sampler_t: case TST_event_t: case TST_error: +#ifndef noCbC + case TST___code: +#endif break; }
--- a/tools/clang/lib/Sema/SemaType.cpp Thu Dec 12 15:22:36 2013 +0900 +++ b/tools/clang/lib/Sema/SemaType.cpp Thu Dec 12 23:38:21 2013 +0900 @@ -712,6 +712,11 @@ case DeclSpec::TST_void: Result = Context.VoidTy; break; +#ifndef noCbC + case DeclSpec::TST___code: + Result = Context.__CodeTy; + break; +#endif case DeclSpec::TST_char: if (DS.getTypeSpecSign() == DeclSpec::TSS_unspecified) Result = Context.CharTy;
--- a/tools/clang/lib/Serialization/ASTCommon.cpp Thu Dec 12 15:22:36 2013 +0900 +++ b/tools/clang/lib/Serialization/ASTCommon.cpp Thu Dec 12 23:38:21 2013 +0900 @@ -72,6 +72,9 @@ case BuiltinType::BuiltinFn: ID = PREDEF_TYPE_BUILTIN_FN; break; +#ifndef noCbC + case BuiltinType::__Code: ID = PREDEF_TYPE___CODE_ID; break; +#endif } return TypeIdx(ID);
--- a/tools/clang/lib/Serialization/ASTReader.cpp Thu Dec 12 15:22:36 2013 +0900 +++ b/tools/clang/lib/Serialization/ASTReader.cpp Thu Dec 12 23:38:21 2013 +0900 @@ -5218,6 +5218,9 @@ switch ((PredefinedTypeIDs)Index) { case PREDEF_TYPE_NULL_ID: return QualType(); case PREDEF_TYPE_VOID_ID: T = Context.VoidTy; break; +#ifndef noCbC + case PREDEF_TYPE___CODE_ID: T = Context.__CodeTy; break; +#endif case PREDEF_TYPE_BOOL_ID: T = Context.BoolTy; break; case PREDEF_TYPE_CHAR_U_ID:
--- a/tools/clang/tools/libclang/CIndex.cpp Thu Dec 12 15:22:36 2013 +0900 +++ b/tools/clang/tools/libclang/CIndex.cpp Thu Dec 12 23:38:21 2013 +0900 @@ -1404,6 +1404,9 @@ switch (TL.getTypePtr()->getKind()) { case BuiltinType::Void: +#ifndef noCbC + case BuiltinType::__Code: +#endif case BuiltinType::NullPtr: case BuiltinType::Dependent: case BuiltinType::OCLImage1d: