summaryrefslogtreecommitdiff
path: root/include/clang/CodeGen/CGFunctionInfo.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/clang/CodeGen/CGFunctionInfo.h')
-rw-r--r--include/clang/CodeGen/CGFunctionInfo.h73
1 files changed, 63 insertions, 10 deletions
diff --git a/include/clang/CodeGen/CGFunctionInfo.h b/include/clang/CodeGen/CGFunctionInfo.h
index d1f05124d5e5..cf64e9f3eeff 100644
--- a/include/clang/CodeGen/CGFunctionInfo.h
+++ b/include/clang/CodeGen/CGFunctionInfo.h
@@ -95,6 +95,8 @@ private:
bool SRetAfterThis : 1; // isIndirect()
bool InReg : 1; // isDirect() || isExtend() || isIndirect()
bool CanBeFlattened: 1; // isDirect()
+ bool SignExt : 1; // isExtend()
+ bool SuppressSRet : 1; // isIndirect()
bool canHavePaddingType() const {
return isDirect() || isExtend() || isIndirect() || isExpand();
@@ -110,13 +112,14 @@ private:
}
ABIArgInfo(Kind K)
- : TheKind(K), PaddingInReg(false), InReg(false) {
+ : TheKind(K), PaddingInReg(false), InReg(false), SuppressSRet(false) {
}
public:
ABIArgInfo()
: TypeData(nullptr), PaddingType(nullptr), DirectOffset(0),
- TheKind(Direct), PaddingInReg(false), InReg(false) {}
+ TheKind(Direct), PaddingInReg(false), InReg(false),
+ SuppressSRet(false) {}
static ABIArgInfo getDirect(llvm::Type *T = nullptr, unsigned Offset = 0,
llvm::Type *Padding = nullptr,
@@ -133,15 +136,38 @@ public:
AI.setInReg(true);
return AI;
}
- static ABIArgInfo getExtend(llvm::Type *T = nullptr) {
+
+ static ABIArgInfo getSignExtend(QualType Ty, llvm::Type *T = nullptr) {
+ assert(Ty->isIntegralOrEnumerationType() && "Unexpected QualType");
auto AI = ABIArgInfo(Extend);
AI.setCoerceToType(T);
AI.setPaddingType(nullptr);
AI.setDirectOffset(0);
+ AI.setSignExt(true);
return AI;
}
- static ABIArgInfo getExtendInReg(llvm::Type *T = nullptr) {
- auto AI = getExtend(T);
+
+ static ABIArgInfo getZeroExtend(QualType Ty, llvm::Type *T = nullptr) {
+ assert(Ty->isIntegralOrEnumerationType() && "Unexpected QualType");
+ auto AI = ABIArgInfo(Extend);
+ AI.setCoerceToType(T);
+ AI.setPaddingType(nullptr);
+ AI.setDirectOffset(0);
+ AI.setSignExt(false);
+ return AI;
+ }
+
+ // ABIArgInfo will record the argument as being extended based on the sign
+ // of its type.
+ static ABIArgInfo getExtend(QualType Ty, llvm::Type *T = nullptr) {
+ assert(Ty->isIntegralOrEnumerationType() && "Unexpected QualType");
+ if (Ty->hasSignedIntegerRepresentation())
+ return getSignExtend(Ty, T);
+ return getZeroExtend(Ty, T);
+ }
+
+ static ABIArgInfo getExtendInReg(QualType Ty, llvm::Type *T = nullptr) {
+ auto AI = getExtend(Ty, T);
AI.setInReg(true);
return AI;
}
@@ -254,6 +280,15 @@ public:
DirectOffset = Offset;
}
+ bool isSignExt() const {
+ assert(isExtend() && "Invalid kind!");
+ return SignExt;
+ }
+ void setSignExt(bool SExt) {
+ assert(isExtend() && "Invalid kind!");
+ SignExt = SExt;
+ }
+
llvm::Type *getPaddingType() const {
return (canHavePaddingType() ? PaddingType : nullptr);
}
@@ -351,7 +386,7 @@ public:
AllocaFieldIndex = FieldIndex;
}
- /// \brief Return true if this field of an inalloca struct should be returned
+ /// Return true if this field of an inalloca struct should be returned
/// to implement a struct return calling convention.
bool getInAllocaSRet() const {
assert(isInAlloca() && "Invalid kind!");
@@ -373,6 +408,16 @@ public:
CanBeFlattened = Flatten;
}
+ bool getSuppressSRet() const {
+ assert(isIndirect() && "Invalid kind!");
+ return SuppressSRet;
+ }
+
+ void setSuppressSRet(bool Suppress) {
+ assert(isIndirect() && "Invalid kind!");
+ SuppressSRet = Suppress;
+ }
+
void dump() const;
};
@@ -461,7 +506,7 @@ class CGFunctionInfo final
unsigned EffectiveCallingConvention : 8;
/// The clang::CallingConv that this was originally created with.
- unsigned ASTCallingConvention : 7;
+ unsigned ASTCallingConvention : 6;
/// Whether this is an instance method.
unsigned InstanceMethod : 1;
@@ -482,6 +527,9 @@ class CGFunctionInfo final
unsigned HasRegParm : 1;
unsigned RegParm : 3;
+ /// Whether this function has nocf_check attribute.
+ unsigned NoCfCheck : 1;
+
RequiredArgs Required;
/// The struct representing all arguments passed in memory. Only used when
@@ -566,6 +614,9 @@ public:
/// Whether this function no longer saves caller registers.
bool isNoCallerSavedRegs() const { return NoCallerSavedRegs; }
+ /// Whether this function has nocf_check attribute.
+ bool isNoCfCheck() const { return NoCfCheck; }
+
/// getASTCallingConvention() - Return the AST-specified calling
/// convention.
CallingConv getASTCallingConvention() const {
@@ -591,7 +642,7 @@ public:
FunctionType::ExtInfo getExtInfo() const {
return FunctionType::ExtInfo(isNoReturn(), getHasRegParm(), getRegParm(),
getASTCallingConvention(), isReturnsRetained(),
- isNoCallerSavedRegs());
+ isNoCallerSavedRegs(), isNoCfCheck());
}
CanQualType getReturnType() const { return getArgsBuffer()[0].type; }
@@ -609,10 +660,10 @@ public:
return getExtParameterInfos()[argIndex];
}
- /// \brief Return true if this function uses inalloca arguments.
+ /// Return true if this function uses inalloca arguments.
bool usesInAlloca() const { return ArgStruct; }
- /// \brief Get the struct type used to represent all the arguments in memory.
+ /// Get the struct type used to represent all the arguments in memory.
llvm::StructType *getArgStruct() const { return ArgStruct; }
CharUnits getArgStructAlignment() const {
return CharUnits::fromQuantity(ArgStructAlign);
@@ -631,6 +682,7 @@ public:
ID.AddBoolean(NoCallerSavedRegs);
ID.AddBoolean(HasRegParm);
ID.AddInteger(RegParm);
+ ID.AddBoolean(NoCfCheck);
ID.AddInteger(Required.getOpaqueData());
ID.AddBoolean(HasExtParameterInfos);
if (HasExtParameterInfos) {
@@ -657,6 +709,7 @@ public:
ID.AddBoolean(info.getNoCallerSavedRegs());
ID.AddBoolean(info.getHasRegParm());
ID.AddInteger(info.getRegParm());
+ ID.AddBoolean(info.getNoCfCheck());
ID.AddInteger(required.getOpaqueData());
ID.AddBoolean(!paramInfos.empty());
if (!paramInfos.empty()) {