Added ParenType type node.
llvm-svn: 121488
diff --git a/clang/lib/Sema/SemaCodeComplete.cpp b/clang/lib/Sema/SemaCodeComplete.cpp
index 0e30a2b..2394629 100644
--- a/clang/lib/Sema/SemaCodeComplete.cpp
+++ b/clang/lib/Sema/SemaCodeComplete.cpp
@@ -1919,6 +1919,9 @@
if (BlockPointerTypeLoc *BlockPtr
= dyn_cast<BlockPointerTypeLoc>(&TL)) {
TL = BlockPtr->getPointeeLoc();
+ // Skip any paren typeloc.
+ while (ParenTypeLoc *ParenPtr = dyn_cast<ParenTypeLoc>(&TL))
+ TL = ParenPtr->getInnerLoc();
Block = dyn_cast<FunctionProtoTypeLoc>(&TL);
}
break;
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 1112d85..522ba36 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -2571,6 +2571,15 @@
FixedType = Context.getPointerType(FixedType);
return Qs.apply(Context, FixedType);
}
+ if (const ParenType* PTy = dyn_cast<ParenType>(Ty)) {
+ QualType Inner = PTy->getInnerType();
+ QualType FixedType =
+ TryToFixInvalidVariablyModifiedType(Inner, Context, SizeIsNegative,
+ Oversized);
+ if (FixedType.isNull()) return FixedType;
+ FixedType = Context.getParenType(FixedType);
+ return Qs.apply(Context, FixedType);
+ }
const VariableArrayType* VLATy = dyn_cast<VariableArrayType>(T);
if (!VLATy)
@@ -3456,7 +3465,7 @@
// - the type R of the function is some kind of typedef or other reference
// to a type name (which eventually refers to a function type).
bool HasPrototype =
- (D.getNumTypeObjects() && D.getTypeObject(0).Fun.hasPrototype) ||
+ (D.isFunctionDeclarator() && D.getFunctionTypeInfo().hasPrototype) ||
(!isa<FunctionType>(R.getTypePtr()) && R->isFunctionProtoType());
NewFD = FunctionDecl::Create(Context, DC,
@@ -3754,7 +3763,7 @@
// declaration NewFD, if they are available. First scavenge them into Params.
llvm::SmallVector<ParmVarDecl*, 16> Params;
if (D.getNumTypeObjects() > 0) {
- DeclaratorChunk::FunctionTypeInfo &FTI = D.getTypeObject(0).Fun;
+ DeclaratorChunk::FunctionTypeInfo &FTI = D.getFunctionTypeInfo();
// Check for C99 6.7.5.3p10 - foo(void) is a non-varargs
// function that takes no arguments, not a function that takes a
@@ -5088,9 +5097,7 @@
void Sema::ActOnFinishKNRParamDeclarations(Scope *S, Declarator &D,
SourceLocation LocAfterDecls) {
- assert(D.getTypeObject(0).Kind == DeclaratorChunk::Function &&
- "Not a function declarator!");
- DeclaratorChunk::FunctionTypeInfo &FTI = D.getTypeObject(0).Fun;
+ DeclaratorChunk::FunctionTypeInfo &FTI = D.getFunctionTypeInfo();
// Verify 6.9.1p6: 'every identifier in the identifier list shall be declared'
// for a K&R function.
@@ -5124,8 +5131,7 @@
Decl *Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope,
Declarator &D) {
assert(getCurFunctionDecl() == 0 && "Function parsing confused");
- assert(D.getTypeObject(0).Kind == DeclaratorChunk::Function &&
- "Not a function declarator!");
+ assert(D.isFunctionDeclarator() && "Not a function declarator!");
Scope *ParentScope = FnBodyScope->getParent();
Decl *DP = HandleDeclarator(ParentScope, D,
diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp
index b5e6321..be1979e 100644
--- a/clang/lib/Sema/SemaDeclCXX.cpp
+++ b/clang/lib/Sema/SemaDeclCXX.cpp
@@ -2835,7 +2835,7 @@
SC = SC_None;
}
- DeclaratorChunk::FunctionTypeInfo &FTI = D.getTypeObject(0).Fun;
+ DeclaratorChunk::FunctionTypeInfo &FTI = D.getFunctionTypeInfo();
if (FTI.TypeQuals != 0) {
if (FTI.TypeQuals & Qualifiers::Const)
Diag(D.getIdentifierLoc(), diag::err_invalid_qualified_constructor)
@@ -2984,7 +2984,7 @@
<< SourceRange(D.getIdentifierLoc());
}
- DeclaratorChunk::FunctionTypeInfo &FTI = D.getTypeObject(0).Fun;
+ DeclaratorChunk::FunctionTypeInfo &FTI = D.getFunctionTypeInfo();
if (FTI.TypeQuals != 0 && !D.isInvalidType()) {
if (FTI.TypeQuals & Qualifiers::Const)
Diag(D.getIdentifierLoc(), diag::err_invalid_qualified_destructor)
@@ -3074,7 +3074,7 @@
Diag(D.getIdentifierLoc(), diag::err_conv_function_with_params);
// Delete the parameters.
- D.getTypeObject(0).Fun.freeArgs();
+ D.getFunctionTypeInfo().freeArgs();
D.setInvalidType();
} else if (Proto->isVariadic()) {
Diag(D.getIdentifierLoc(), diag::err_conv_function_variadic);
diff --git a/clang/lib/Sema/SemaExceptionSpec.cpp b/clang/lib/Sema/SemaExceptionSpec.cpp
index c902e77..885e52d 100644
--- a/clang/lib/Sema/SemaExceptionSpec.cpp
+++ b/clang/lib/Sema/SemaExceptionSpec.cpp
@@ -81,6 +81,7 @@
/// to member to a function with an exception specification. This means that
/// it is invalid to add another level of indirection.
bool Sema::CheckDistantExceptionSpec(QualType T) {
+ T = T.IgnoreParens();
if (const PointerType *PT = T->getAs<PointerType>())
T = PT->getPointeeType();
else if (const MemberPointerType *PT = T->getAs<MemberPointerType>())
@@ -88,6 +89,7 @@
else
return false;
+ T = T.IgnoreParens();
const FunctionProtoType *FnT = T->getAs<FunctionProtoType>();
if (!FnT)
return false;
diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp
index ad0d42a..7539a56 100644
--- a/clang/lib/Sema/SemaTemplate.cpp
+++ b/clang/lib/Sema/SemaTemplate.cpp
@@ -4336,9 +4336,7 @@
MultiTemplateParamsArg TemplateParameterLists,
Declarator &D) {
assert(getCurFunctionDecl() == 0 && "Function parsing confused");
- assert(D.getTypeObject(0).Kind == DeclaratorChunk::Function &&
- "Not a function declarator!");
- DeclaratorChunk::FunctionTypeInfo &FTI = D.getTypeObject(0).Fun;
+ DeclaratorChunk::FunctionTypeInfo &FTI = D.getFunctionTypeInfo();
if (FTI.hasPrototype) {
// FIXME: Diagnose arguments without names in C.
diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp
index 5f86010..23c159f 100644
--- a/clang/lib/Sema/SemaType.cpp
+++ b/clang/lib/Sema/SemaType.cpp
@@ -521,6 +521,11 @@
return Context.getQualifiedType(T, Qs);
}
+/// \brief Build a paren type including \p T.
+QualType Sema::BuildParenType(QualType T) {
+ return Context.getParenType(T);
+}
+
/// \brief Build a pointer type.
///
/// \param T The type to which we'll be building a pointer.
@@ -1002,7 +1007,7 @@
// Check for auto functions and trailing return type and adjust the
// return type accordingly.
if (getLangOptions().CPlusPlus0x && D.isFunctionDeclarator()) {
- const DeclaratorChunk::FunctionTypeInfo &FTI = D.getTypeObject(0).Fun;
+ const DeclaratorChunk::FunctionTypeInfo &FTI = D.getFunctionTypeInfo();
if (T == Context.UndeducedAutoTy) {
if (FTI.TrailingReturnType) {
T = GetTypeFromParser(ParsedType::getFromOpaquePtr(FTI.TrailingReturnType),
@@ -1082,6 +1087,9 @@
DeclaratorChunk &DeclType = D.getTypeObject(e-i-1);
switch (DeclType.Kind) {
default: assert(0 && "Unknown decltype!");
+ case DeclaratorChunk::Paren:
+ T = BuildParenType(T);
+ break;
case DeclaratorChunk::BlockPointer:
// If blocks are disabled, emit an error.
if (!LangOpts.Blocks)
@@ -1678,6 +1686,11 @@
}
// FIXME: exception specs
}
+ void VisitParenTypeLoc(ParenTypeLoc TL) {
+ assert(Chunk.Kind == DeclaratorChunk::Paren);
+ TL.setLParenLoc(Chunk.Loc);
+ TL.setRParenLoc(Chunk.EndLoc);
+ }
void VisitTypeLoc(TypeLoc TL) {
llvm_unreachable("unsupported TypeLoc kind in declarator!");
diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h
index c0bafc7..9f6f84b 100644
--- a/clang/lib/Sema/TreeTransform.h
+++ b/clang/lib/Sema/TreeTransform.h
@@ -519,6 +519,14 @@
SourceLocation TemplateLoc,
const TemplateArgumentListInfo &Args);
+ /// \brief Build a new parenthesized type.
+ ///
+ /// By default, builds a new ParenType type from the inner type.
+ /// Subclasses may override this routine to provide different behavior.
+ QualType RebuildParenType(QualType InnerType) {
+ return SemaRef.Context.getParenType(InnerType);
+ }
+
/// \brief Build a new qualified name type.
///
/// By default, builds a new ElaboratedType type from the keyword,
@@ -3372,6 +3380,28 @@
}
template<typename Derived>
+QualType
+TreeTransform<Derived>::TransformParenType(TypeLocBuilder &TLB,
+ ParenTypeLoc TL) {
+ QualType Inner = getDerived().TransformType(TLB, TL.getInnerLoc());
+ if (Inner.isNull())
+ return QualType();
+
+ QualType Result = TL.getType();
+ if (getDerived().AlwaysRebuild() ||
+ Inner != TL.getInnerLoc().getType()) {
+ Result = getDerived().RebuildParenType(Inner);
+ if (Result.isNull())
+ return QualType();
+ }
+
+ ParenTypeLoc NewTL = TLB.push<ParenTypeLoc>(Result);
+ NewTL.setLParenLoc(TL.getLParenLoc());
+ NewTL.setRParenLoc(TL.getRParenLoc());
+ return Result;
+}
+
+template<typename Derived>
QualType TreeTransform<Derived>::TransformDependentNameType(TypeLocBuilder &TLB,
DependentNameTypeLoc TL) {
DependentNameType *T = TL.getTypePtr();