aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema/SemaDecl.cpp
diff options
context:
space:
mode:
authorAbramo Bagnara <abramo.bagnara@bugseng.com>2012-11-08 14:44:42 +0000
committerAbramo Bagnara <abramo.bagnara@bugseng.com>2012-11-08 14:44:42 +0000
commit4c5750e0d1c1dfc091689e3daa96ed4ccfa36dca (patch)
treedd8875ffa798153aca45bd30e6213fcad0946e8c /lib/Sema/SemaDecl.cpp
parent13fd684ee2c7578177b7c741e8eeec91ae628fcf (diff)
Fixed converted ConstantArrayTypeLoc range. Added a missing testcase for ConstructorDecl source range.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@167583 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaDecl.cpp')
-rw-r--r--lib/Sema/SemaDecl.cpp90
1 files changed, 71 insertions, 19 deletions
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index 52ee80f833..3292dce516 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -3875,6 +3875,53 @@ static QualType TryToFixInvalidVariablyModifiedType(QualType T,
Res, ArrayType::Normal, 0);
}
+/// FixInvalidVariablyModifiedTypeLoc
+static void
+FixInvalidVariablyModifiedTypeLoc(TypeLoc SrcTL, TypeLoc DstTL) {
+ if (PointerTypeLoc* SrcPTL = dyn_cast<PointerTypeLoc>(&SrcTL)) {
+ PointerTypeLoc* DstPTL = cast<PointerTypeLoc>(&DstTL);
+ FixInvalidVariablyModifiedTypeLoc(SrcPTL->getPointeeLoc(),
+ DstPTL->getPointeeLoc());
+ DstPTL->setStarLoc(SrcPTL->getStarLoc());
+ return;
+ }
+ if (ParenTypeLoc* SrcPTL = dyn_cast<ParenTypeLoc>(&SrcTL)) {
+ ParenTypeLoc* DstPTL = cast<ParenTypeLoc>(&DstTL);
+ FixInvalidVariablyModifiedTypeLoc(SrcPTL->getInnerLoc(),
+ DstPTL->getInnerLoc());
+ DstPTL->setLParenLoc(SrcPTL->getLParenLoc());
+ DstPTL->setRParenLoc(SrcPTL->getRParenLoc());
+ return;
+ }
+ ArrayTypeLoc* SrcATL = cast<ArrayTypeLoc>(&SrcTL);
+ ArrayTypeLoc* DstATL = cast<ArrayTypeLoc>(&DstTL);
+ TypeLoc SrcElemTL = SrcATL->getElementLoc();
+ TypeLoc DstElemTL = DstATL->getElementLoc();
+ DstElemTL.initializeFullCopy(SrcElemTL);
+ DstATL->setLBracketLoc(SrcATL->getLBracketLoc());
+ DstATL->setSizeExpr(SrcATL->getSizeExpr());
+ DstATL->setRBracketLoc(SrcATL->getRBracketLoc());
+}
+
+/// TryToFixInvalidVariablyModifiedTypeSourceInfo - Helper method to turn
+/// variable array types into constant array types in certain situations
+/// which would otherwise be errors (for GCC compatibility).
+static TypeSourceInfo*
+TryToFixInvalidVariablyModifiedTypeSourceInfo(TypeSourceInfo *TInfo,
+ ASTContext &Context,
+ bool &SizeIsNegative,
+ llvm::APSInt &Oversized) {
+ QualType FixedTy
+ = TryToFixInvalidVariablyModifiedType(TInfo->getType(), Context,
+ SizeIsNegative, Oversized);
+ if (FixedTy.isNull())
+ return 0;
+ TypeSourceInfo *FixedTInfo = Context.getTrivialTypeSourceInfo(FixedTy);
+ FixInvalidVariablyModifiedTypeLoc(TInfo->getTypeLoc(),
+ FixedTInfo->getTypeLoc());
+ return FixedTInfo;
+}
+
/// \brief Register the given locally-scoped external C declaration so
/// that it can be found later for redeclarations
void
@@ -4002,19 +4049,21 @@ Sema::CheckTypedefForVariablyModifiedType(Scope *S, TypedefNameDecl *NewTD) {
// then it shall have block scope.
// Note that variably modified types must be fixed before merging the decl so
// that redeclarations will match.
- QualType T = NewTD->getUnderlyingType();
+ TypeSourceInfo *TInfo = NewTD->getTypeSourceInfo();
+ QualType T = TInfo->getType();
if (T->isVariablyModifiedType()) {
getCurFunction()->setHasBranchProtectedScope();
if (S->getFnParent() == 0) {
bool SizeIsNegative;
llvm::APSInt Oversized;
- QualType FixedTy =
- TryToFixInvalidVariablyModifiedType(T, Context, SizeIsNegative,
- Oversized);
- if (!FixedTy.isNull()) {
+ TypeSourceInfo *FixedTInfo =
+ TryToFixInvalidVariablyModifiedTypeSourceInfo(TInfo, Context,
+ SizeIsNegative,
+ Oversized);
+ if (FixedTInfo) {
Diag(NewTD->getLocation(), diag::warn_illegal_constant_array_size);
- NewTD->setTypeSourceInfo(Context.getTrivialTypeSourceInfo(FixedTy));
+ NewTD->setTypeSourceInfo(FixedTInfo);
} else {
if (SizeIsNegative)
Diag(NewTD->getLocation(), diag::err_typecheck_negative_array_size);
@@ -4574,7 +4623,8 @@ bool Sema::CheckVariableDeclaration(VarDecl *NewVD,
if (NewVD->isInvalidDecl())
return false;
- QualType T = NewVD->getType();
+ TypeSourceInfo *TInfo = NewVD->getTypeSourceInfo();
+ QualType T = TInfo->getType();
if (T->isObjCObjectType()) {
Diag(NewVD->getLocation(), diag::err_statically_allocated_object)
@@ -4621,11 +4671,10 @@ bool Sema::CheckVariableDeclaration(VarDecl *NewVD,
(T->isVariableArrayType() && NewVD->hasGlobalStorage())) {
bool SizeIsNegative;
llvm::APSInt Oversized;
- QualType FixedTy =
- TryToFixInvalidVariablyModifiedType(T, Context, SizeIsNegative,
- Oversized);
-
- if (FixedTy.isNull() && T->isVariableArrayType()) {
+ TypeSourceInfo *FixedTInfo =
+ TryToFixInvalidVariablyModifiedTypeSourceInfo(TInfo, Context,
+ SizeIsNegative, Oversized);
+ if (FixedTInfo == 0 && T->isVariableArrayType()) {
const VariableArrayType *VAT = Context.getAsVariableArrayType(T);
// FIXME: This won't give the correct result for
// int a[10][n];
@@ -4644,7 +4693,7 @@ bool Sema::CheckVariableDeclaration(VarDecl *NewVD,
return false;
}
- if (FixedTy.isNull()) {
+ if (FixedTInfo == 0) {
if (NewVD->isFileVarDecl())
Diag(NewVD->getLocation(), diag::err_vm_decl_in_file_scope);
else
@@ -4654,7 +4703,7 @@ bool Sema::CheckVariableDeclaration(VarDecl *NewVD,
}
Diag(NewVD->getLocation(), diag::warn_illegal_constant_array_size);
- NewVD->setType(FixedTy);
+ NewVD->setTypeSourceInfo(FixedTInfo);
}
if (Previous.empty() && NewVD->isExternC()) {
@@ -9544,12 +9593,15 @@ FieldDecl *Sema::CheckFieldDecl(DeclarationName Name, QualType T,
if (!InvalidDecl && T->isVariablyModifiedType()) {
bool SizeIsNegative;
llvm::APSInt Oversized;
- QualType FixedTy = TryToFixInvalidVariablyModifiedType(T, Context,
- SizeIsNegative,
- Oversized);
- if (!FixedTy.isNull()) {
+
+ TypeSourceInfo *FixedTInfo =
+ TryToFixInvalidVariablyModifiedTypeSourceInfo(TInfo, Context,
+ SizeIsNegative,
+ Oversized);
+ if (FixedTInfo) {
Diag(Loc, diag::warn_illegal_constant_array_size);
- T = FixedTy;
+ TInfo = FixedTInfo;
+ T = FixedTInfo->getType();
} else {
if (SizeIsNegative)
Diag(Loc, diag::err_typecheck_negative_array_size);