summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
authorReid Kleckner <reid@kleckner.net>2013-06-24 17:51:48 +0000
committerReid Kleckner <reid@kleckner.net>2013-06-24 17:51:48 +0000
commit8a36502a60326473ec187eaa954e47beab25a8fb (patch)
tree870e495d25ecd31f373f025e3e21a1adee894187 /clang/lib
parent52dd02d8ef35221568f9afd79f4b4f7b7f7bfda5 (diff)
downloadbcm5719-llvm-8a36502a60326473ec187eaa954e47beab25a8fb.tar.gz
bcm5719-llvm-8a36502a60326473ec187eaa954e47beab25a8fb.zip
[AST] Introduce a new DecayedType sugar node
The goal of this sugar node is to be able to look at an arbitrary FunctionType and tell if any of the parameters were decayed from an array or function type. Ultimately this is necessary to implement Microsoft's C++ name mangling scheme, which mangles decayed arrays differently from normal pointers. Reviewers: rsmith Differential Revision: http://llvm-reviews.chandlerc.com/D1014 llvm-svn: 184763
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/AST/ASTContext.cpp60
-rw-r--r--clang/lib/AST/ASTImporter.cpp7
-rw-r--r--clang/lib/AST/Decl.cpp8
-rw-r--r--clang/lib/AST/ItaniumMangle.cpp1
-rw-r--r--clang/lib/AST/TypePrinter.cpp9
-rw-r--r--clang/lib/CodeGen/CGDebugInfo.cpp4
-rw-r--r--clang/lib/CodeGen/CodeGenFunction.cpp4
-rw-r--r--clang/lib/Sema/SemaExpr.cpp2
-rw-r--r--clang/lib/Sema/SemaType.cpp7
-rw-r--r--clang/lib/Sema/TreeTransform.h16
-rw-r--r--clang/lib/Serialization/ASTReader.cpp15
-rw-r--r--clang/lib/Serialization/ASTWriter.cpp8
12 files changed, 121 insertions, 20 deletions
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp
index 70c933e7521..91059400761 100644
--- a/clang/lib/AST/ASTContext.cpp
+++ b/clang/lib/AST/ASTContext.cpp
@@ -1615,6 +1615,8 @@ ASTContext::getTypeInfoImpl(const Type *T) const {
}
case Type::ObjCObject:
return getTypeInfo(cast<ObjCObjectType>(T)->getBaseType().getTypePtr());
+ case Type::Decayed:
+ return getTypeInfo(cast<DecayedType>(T)->getDecayedType().getTypePtr());
case Type::ObjCInterface: {
const ObjCInterfaceType *ObjCI = cast<ObjCInterfaceType>(T);
const ASTRecordLayout &Layout = getASTObjCInterfaceLayout(ObjCI->getDecl());
@@ -2167,6 +2169,45 @@ QualType ASTContext::getPointerType(QualType T) const {
return QualType(New, 0);
}
+QualType ASTContext::getDecayedType(QualType T) const {
+ assert((T->isArrayType() || T->isFunctionType()) && "T does not decay");
+
+ llvm::FoldingSetNodeID ID;
+ DecayedType::Profile(ID, T);
+ void *InsertPos = 0;
+ if (DecayedType *DT = DecayedTypes.FindNodeOrInsertPos(ID, InsertPos))
+ return QualType(DT, 0);
+
+ QualType Decayed;
+
+ // C99 6.7.5.3p7:
+ // A declaration of a parameter as "array of type" shall be
+ // adjusted to "qualified pointer to type", where the type
+ // qualifiers (if any) are those specified within the [ and ] of
+ // the array type derivation.
+ if (T->isArrayType())
+ Decayed = getArrayDecayedType(T);
+
+ // C99 6.7.5.3p8:
+ // A declaration of a parameter as "function returning type"
+ // shall be adjusted to "pointer to function returning type", as
+ // in 6.3.2.1.
+ if (T->isFunctionType())
+ Decayed = getPointerType(T);
+
+ QualType Canonical = getCanonicalType(Decayed);
+
+ // Get the new insert position for the node we care about.
+ DecayedType *NewIP = DecayedTypes.FindNodeOrInsertPos(ID, InsertPos);
+ assert(NewIP == 0 && "Shouldn't be in the map!"); (void)NewIP;
+
+ DecayedType *New =
+ new (*this, TypeAlignment) DecayedType(T, Decayed, Canonical);
+ Types.push_back(New);
+ DecayedTypes.InsertNode(New, InsertPos);
+ return QualType(New, 0);
+}
+
/// getBlockPointerType - Return the uniqued reference to the type for
/// a pointer to the specified block.
QualType ASTContext::getBlockPointerType(QualType T) const {
@@ -4154,22 +4195,9 @@ const ArrayType *ASTContext::getAsArrayType(QualType T) const {
}
QualType ASTContext::getAdjustedParameterType(QualType T) const {
- // C99 6.7.5.3p7:
- // A declaration of a parameter as "array of type" shall be
- // adjusted to "qualified pointer to type", where the type
- // qualifiers (if any) are those specified within the [ and ] of
- // the array type derivation.
- if (T->isArrayType())
- return getArrayDecayedType(T);
-
- // C99 6.7.5.3p8:
- // A declaration of a parameter as "function returning type"
- // shall be adjusted to "pointer to function returning type", as
- // in 6.3.2.1.
- if (T->isFunctionType())
- return getPointerType(T);
-
- return T;
+ if (T->isArrayType() || T->isFunctionType())
+ return getDecayedType(T);
+ return T;
}
QualType ASTContext::getSignatureParameterType(QualType T) const {
diff --git a/clang/lib/AST/ASTImporter.cpp b/clang/lib/AST/ASTImporter.cpp
index 41a67af64d6..84904580162 100644
--- a/clang/lib/AST/ASTImporter.cpp
+++ b/clang/lib/AST/ASTImporter.cpp
@@ -400,6 +400,13 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
return false;
break;
+ case Type::Decayed:
+ if (!IsStructurallyEquivalent(Context,
+ cast<DecayedType>(T1)->getPointeeType(),
+ cast<DecayedType>(T2)->getPointeeType()))
+ return false;
+ break;
+
case Type::Pointer:
if (!IsStructurallyEquivalent(Context,
cast<PointerType>(T1)->getPointeeType(),
diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp
index c799161e9b7..9702d032453 100644
--- a/clang/lib/AST/Decl.cpp
+++ b/clang/lib/AST/Decl.cpp
@@ -1995,6 +1995,14 @@ ParmVarDecl *ParmVarDecl::Create(ASTContext &C, DeclContext *DC,
S, DefArg);
}
+QualType ParmVarDecl::getOriginalType() const {
+ TypeSourceInfo *TSI = getTypeSourceInfo();
+ QualType T = TSI ? TSI->getType() : getType();
+ if (const DecayedType *DT = dyn_cast<DecayedType>(T))
+ return DT->getOriginalType();
+ return T;
+}
+
ParmVarDecl *ParmVarDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
void *Mem = AllocateDeserializedDecl(C, ID, sizeof(ParmVarDecl));
return new (Mem) ParmVarDecl(ParmVar, 0, SourceLocation(), SourceLocation(),
diff --git a/clang/lib/AST/ItaniumMangle.cpp b/clang/lib/AST/ItaniumMangle.cpp
index 065465aa59e..7102bf349b2 100644
--- a/clang/lib/AST/ItaniumMangle.cpp
+++ b/clang/lib/AST/ItaniumMangle.cpp
@@ -828,6 +828,7 @@ void CXXNameMangler::mangleUnresolvedPrefix(NestedNameSpecifier *qualifier,
switch (type->getTypeClass()) {
case Type::Builtin:
case Type::Complex:
+ case Type::Decayed:
case Type::Pointer:
case Type::BlockPointer:
case Type::LValueReference:
diff --git a/clang/lib/AST/TypePrinter.cpp b/clang/lib/AST/TypePrinter.cpp
index 2c439128f2d..d19c6a94508 100644
--- a/clang/lib/AST/TypePrinter.cpp
+++ b/clang/lib/AST/TypePrinter.cpp
@@ -201,6 +201,7 @@ bool TypePrinter::canPrefixQualifiers(const Type *T,
NeedARCStrongQualifier = true;
// Fall through
+ case Type::Decayed:
case Type::Pointer:
case Type::BlockPointer:
case Type::LValueReference:
@@ -468,6 +469,14 @@ void TypePrinter::printVariableArrayAfter(const VariableArrayType *T,
printAfter(T->getElementType(), OS);
}
+void TypePrinter::printDecayedBefore(const DecayedType *T, raw_ostream &OS) {
+ // Print as though it's a pointer.
+ printBefore(T->getDecayedType(), OS);
+}
+void TypePrinter::printDecayedAfter(const DecayedType *T, raw_ostream &OS) {
+ printAfter(T->getDecayedType(), OS);
+}
+
void TypePrinter::printDependentSizedArrayBefore(
const DependentSizedArrayType *T,
raw_ostream &OS) {
diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp
index e38327a9270..9d2b23ed185 100644
--- a/clang/lib/CodeGen/CGDebugInfo.cpp
+++ b/clang/lib/CodeGen/CGDebugInfo.cpp
@@ -2069,6 +2069,10 @@ llvm::DIType CGDebugInfo::CreateTypeNode(QualType Ty, llvm::DIFile Unit,
return CreateType(cast<ComplexType>(Ty));
case Type::Pointer:
return CreateType(cast<PointerType>(Ty), Unit);
+ case Type::Decayed:
+ // Decayed types are just pointers in LLVM and DWARF.
+ return CreateType(
+ cast<PointerType>(cast<DecayedType>(Ty)->getDecayedType()), Unit);
case Type::BlockPointer:
return CreateType(cast<BlockPointerType>(Ty), Unit);
case Type::Typedef:
diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp
index 297fc655e44..c6b498cd586 100644
--- a/clang/lib/CodeGen/CodeGenFunction.cpp
+++ b/clang/lib/CodeGen/CodeGenFunction.cpp
@@ -1273,6 +1273,10 @@ void CodeGenFunction::EmitVariablyModifiedType(QualType type) {
case Type::ObjCObjectPointer:
llvm_unreachable("type class is never variably-modified!");
+ case Type::Decayed:
+ type = cast<DecayedType>(ty)->getPointeeType();
+ break;
+
case Type::Pointer:
type = cast<PointerType>(ty)->getPointeeType();
break;
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 27e8962f71b..1d2f39c0da3 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -4021,6 +4021,8 @@ bool Sema::GatherArgumentsForCall(SourceLocation CallLoc,
static void DiagnoseCalleeStaticArrayParam(Sema &S, ParmVarDecl *PVD) {
TypeLoc TL = PVD->getTypeSourceInfo()->getTypeLoc();
+ if (DecayedTypeLoc DTL = TL.getAs<DecayedTypeLoc>())
+ TL = DTL.getOriginalLoc();
if (ArrayTypeLoc ATL = TL.getAs<ArrayTypeLoc>())
S.Diag(PVD->getLocation(), diag::note_callee_static_array)
<< ATL.getLocalSourceRange();
diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp
index f5a28966f86..e1f0739aea7 100644
--- a/clang/lib/Sema/SemaType.cpp
+++ b/clang/lib/Sema/SemaType.cpp
@@ -2844,10 +2844,6 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state,
QualType ArgTy = Param->getType();
assert(!ArgTy.isNull() && "Couldn't parse type?");
- // Adjust the parameter type.
- assert((ArgTy == Context.getAdjustedParameterType(ArgTy)) &&
- "Unadjusted type?");
-
// Look for 'void'. void is allowed only as a single argument to a
// function with no other parameters (C99 6.7.5.3p10). We record
// int(void) as a FunctionProtoType with an empty argument list.
@@ -3577,6 +3573,9 @@ namespace {
void VisitQualifiedTypeLoc(QualifiedTypeLoc TL) {
llvm_unreachable("qualified type locs not expected here!");
}
+ void VisitDecayedTypeLoc(DecayedTypeLoc TL) {
+ llvm_unreachable("decayed type locs not expected here!");
+ }
void VisitAttributedTypeLoc(AttributedTypeLoc TL) {
fillAttributedTypeLoc(TL, Chunk.getAttrs());
diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h
index 86624c580e5..9fbbe2cf1d5 100644
--- a/clang/lib/Sema/TreeTransform.h
+++ b/clang/lib/Sema/TreeTransform.h
@@ -3586,6 +3586,22 @@ QualType TreeTransform<Derived>::TransformComplexType(TypeLocBuilder &TLB,
}
template<typename Derived>
+QualType TreeTransform<Derived>::TransformDecayedType(TypeLocBuilder &TLB,
+ DecayedTypeLoc TL) {
+ QualType OriginalType = getDerived().TransformType(TLB, TL.getOriginalLoc());
+ if (OriginalType.isNull())
+ return QualType();
+
+ QualType Result = TL.getType();
+ if (getDerived().AlwaysRebuild() ||
+ OriginalType != TL.getOriginalLoc().getType())
+ Result = SemaRef.Context.getDecayedType(OriginalType);
+ TLB.push<DecayedTypeLoc>(Result);
+ // Nothing to set for DecayedTypeLoc.
+ return Result;
+}
+
+template<typename Derived>
QualType TreeTransform<Derived>::TransformPointerType(TypeLocBuilder &TLB,
PointerTypeLoc TL) {
QualType PointeeType
diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp
index f33e0e14cf6..052bef9e5be 100644
--- a/clang/lib/Serialization/ASTReader.cpp
+++ b/clang/lib/Serialization/ASTReader.cpp
@@ -4531,6 +4531,18 @@ QualType ASTReader::readTypeRecord(unsigned Index) {
return Context.getPointerType(PointeeType);
}
+ case TYPE_DECAYED: {
+ if (Record.size() != 1) {
+ Error("Incorrect encoding of decayed type");
+ return QualType();
+ }
+ QualType OriginalType = readType(*Loc.F, Record, Idx);
+ QualType DT = Context.getAdjustedParameterType(OriginalType);
+ if (!isa<DecayedType>(DT))
+ Error("Decayed type does not decay");
+ return DT;
+ }
+
case TYPE_BLOCK_POINTER: {
if (Record.size() != 1) {
Error("Incorrect encoding of block pointer type");
@@ -4977,6 +4989,9 @@ void TypeLocReader::VisitComplexTypeLoc(ComplexTypeLoc TL) {
void TypeLocReader::VisitPointerTypeLoc(PointerTypeLoc TL) {
TL.setStarLoc(ReadSourceLocation(Record, Idx));
}
+void TypeLocReader::VisitDecayedTypeLoc(DecayedTypeLoc TL) {
+ // nothing to do
+}
void TypeLocReader::VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL) {
TL.setCaretLoc(ReadSourceLocation(Record, Idx));
}
diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp
index 3654ec27f40..4a4128b4cfd 100644
--- a/clang/lib/Serialization/ASTWriter.cpp
+++ b/clang/lib/Serialization/ASTWriter.cpp
@@ -108,6 +108,11 @@ void ASTTypeWriter::VisitPointerType(const PointerType *T) {
Code = TYPE_POINTER;
}
+void ASTTypeWriter::VisitDecayedType(const DecayedType *T) {
+ Writer.AddTypeRef(T->getOriginalType(), Record);
+ Code = TYPE_DECAYED;
+}
+
void ASTTypeWriter::VisitBlockPointerType(const BlockPointerType *T) {
Writer.AddTypeRef(T->getPointeeType(), Record);
Code = TYPE_BLOCK_POINTER;
@@ -447,6 +452,9 @@ void TypeLocWriter::VisitComplexTypeLoc(ComplexTypeLoc TL) {
void TypeLocWriter::VisitPointerTypeLoc(PointerTypeLoc TL) {
Writer.AddSourceLocation(TL.getStarLoc(), Record);
}
+void TypeLocWriter::VisitDecayedTypeLoc(DecayedTypeLoc TL) {
+ // nothing to do
+}
void TypeLocWriter::VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL) {
Writer.AddSourceLocation(TL.getCaretLoc(), Record);
}
OpenPOWER on IntegriCloud